Cập nhật gần đây Trang 2 Toggle Comment Threads | Phím tắt

  • Hình đại diện của Không hiểu

    Viet nguyen van 10:11 am on May 23, 2019 Liên kết tĩnh | Trả lời
    Tags: Dung lượng, IIS,   

    Giảm dung lượng trên hệ thống Server – Xóa các file không cần thiết 


    Đối với các server thuê dung lượng ít thì việc xóa bỏ các file không cần thiết là một điều quan trọng. Ngoài ra nó còn giúp hệ thống server vận hành tốt hơn


    Tìm kiếm các tập tin dung lượng lớn

    Bước 1: Mở ổ đĩa cần tìm các tập tin có dung lượng lớn. Nhập vào mục tìm kiếm dòng lệnh size:gigantic

    tim kiem size gigantic

    Bước 2: Hệ thống tự động tìm kiếm và hiển thị các tập tin có dung lượng lớn hơn 128MB sau đó bạn sắp xếp từ dung lượng cao đến thấp. Bạn có thể xóa nó để tăng đáng kể dung lượng ổ đĩa bằng cách nhấn chuột phải vào tập tin chọn Delete hoặc nhấn Shift + Delete để xóa vĩnh viễn nó khỏi hệ thống.

    Xóa thư mục Log trên IIS

    Các bạn truy cập vào đường dẫn thư mục %SystemDrive%\inetpub\logs\LogFiles vào chọn tất cả thư mục trong đó để xóa. Nếu bạn muốn xem lại thì có thể copy sang ở cứng di dộng hoặc sài google drive hoặc dropbox

    xoa file log tren iis

    Xóa file log trong SQL Server

    Khi tạo một CSDL trong SQL Server, tự động sẽ sinh ra hai tệp là tệp đuôi .MDF và .LDF. Bạn thấy hình bên dưới dữ liệu chỉ có 14MB mà file log tới 195MB

    database properties log

    Để xóa file log bạn sử dụng câu lệnh sau

    USE vnn_mastercode;
    GO 
    -- Truncate the log by changing the database recovery model to SIMPLE.
    ALTER DATABASE vnn_mastercode
    SET RECOVERY SIMPLE;
    GO
    -- Shrink the truncated log file to 1 Mb.
    DBCC SHRINKFILE (vnn_mastercode_Log, 1);
    GO
    -- Reset the database recovery model.
    ALTER DATABASE vnn_mastercode
    SET RECOVERY FULL;
    GO
    

    Sau khi thực hiện lệnh trên xong bạn sẽ thấy kết quả file log giờ chỉ còn 1MB. Bạn có thể hiểu phương pháp này theo cách giải thích sau

    • Có 3 chế độ Recovery trong SQL Server: FULL, SIMPLE và BULK LOGGED. Chế độ mặc định là FULL. Bạn có thể vào phần Option của database, xem trong Recovery Model. Khi ở chế độ này, bất kì một transaction nào, kể cả khi đã commit cũng đều được lưu trong LOG, do đó có thể dựa vào những Transaction này để “quay lui (rollback)” DB về bất kì thời điểm nào. Vì thế với những DB có Transaction nhiều, DATA ít thì file LOG vẫn có thể rất lớn.
    • Đầu tiên SET RECOVERY của DB về SIMPLE, ở chế độ này sau khi Transaction được COMMIT, sẽ tự động xóa. Do vậy File LOG của database ở chế độ này thường rất nhỏ.
    • Dùng DBCC SHRINKFILE để SHRINK file log xuống còn 1 Mb. Nếu không set Recovery về SIMPLE, thì sẽ ko thể xóa bỏ hết các Transaction đã được COMMIT. SHRINKFILE chỉ thu dọn và sắp xếp và phân bố lại dữ liệu, bỏ các vùng trống để giải phóng bộ nhớ, chứ không phải xóa dữ liệu. Vì thế ở chế độ FULL, SHRINKFILE hầu như ko tác dụng, hoặc nếu có thì file LOG dung lượng giảm đi ko đáng kể.
    • Sau đó SET RECOVERY về lại FULL. Trên MSDN cũng khuyên nếu muốn Backup LOG, các bạn nên chuyển về chế độ SIMPLE, hơn là backup LOG với Truncate_Only và No_LOG.
    database properties log
    delete log file database
     
  • Hình đại diện của Không hiểu

    Viet nguyen van 6:20 pm on May 22, 2019 Liên kết tĩnh | Trả lời  

    Sử dụng trigger trong SQL qua ví dụ cơ bản. 

    Trigger là gì ?

    ?

    Hiểu đơn giản thì Trigger là một stored procedure không có tham số. Trigger thực thi một cách tự động khi một trong ba câu lệnh Insert, Update, Delete làm thay đổi dữ liệu trên bảng có chứa trigger. 

    Cú pháp của Trigger

    CREATE TRIGGER tên_trigger ON tên_bảng
    FOR {DELETE, INSERT, UPDATE}
    AS 
      câu_lệnh_sql
    
    

    Trigger dùng làm gì ?

    • Trigger thường được sử dụng để kiểm tra ràng buộc (check constraints) trên nhiều quan hệ (nhiều bảng/table) hoặc trên nhiều dòng (nhiều record) của bảng.
    • Ngoài ra việc sử dụng Trigger để chương trình có những hàm chạy ngầm nhằm phục vụ nhưng trường hợp hữu hạn và thường không sử dụng cho mục đích kinh doanh hoặc giao dịch. Đọc thêm tại đây

    Bài toán đặt ra.

    • Bạn có 2 bảng kho hàng và đặt hàng liên kết với nhau bởi mã hàng.
    • Khi người dùng đặt hàng hãy tự động cập nhật số lượng tồn trong bảng kho hàng.

    Giải pháp

    • Khi người dùng đặt hàng ta chỉ có 3 loại thao tác chính với CSDL là : Insert, Delete, Update
    • Vậy chỉ cần tạo 3 trigger tương ứng là ok 
    • Người dùng đặt hàngSố lượng còn trong kho = Số lượng còn – Số lượt đặt
    • Người dùng hủy không đặt hàng nữa: Số lượng còn trong kho = Số lượng còn + Số lượt đặt
    • Người dùng cập nhật Số lượng đặt => Số lượng còn tăng giảm tùy ý

    Vấn đề

    • Ở 2 trường hợp insert và delete ta thực hiện bình thường. Nhưng trong trường hợp update Số lượng hàng tồn sẽ sảy ra trong 3 trường hợp sau.
    1. Số lượng đặt ban đầu = 5 sau đó tăng lên 10 => số lượng trong kho sẽ giảm 10 tương ứng
    2. Số lượng đặt lúc này = 10 sau đó giảm xuống 3 => số lượng trong kho sẽ tăng 7 tương ứng
    • Tận dụng việc trong sql câu lệnh update = Insert new row To Delete old row cõ nghĩa là khi thực hiện update CSDL trong sql sẽ chạy việc insert dữ liệu mới trước sau đó sẽ xóa đi bảng cũ.

    Giải quyết vấn đề

    • Tận dụng việc sử dụng Trigger luôn tồn tại 2 bảng inserted và deleted ta sẽ rút ra 1 công thức cập nhật trung trong mọi trường hợp
    SLTonKhoCu = SLTonKhoCu - inserted.SLDatHang + deleted.SLDatHang
    
    

    Thực hiện qua ví dụ nhỏ

    1. Ban đầu thêm dữ liệu và select nó ra 
    1. Đặt hàng 5 sản phẩm với mã là 1

     

    1. Cập nhật lên 10
    1. Cập nhật về 3
    1. Cập nhật một số thông tin khác mà không liên quan đến số lượng
    1. Xóa đơn đặt hàng

    Source code bài toàn 

    1. Trigger thêm
    1. Trigger Xóa
    1. Trigger Sửa

    /* cập nhật hàng trong kho sau khi đặt hàng hoặc cập nhật */
    CREATE TRIGGER trg_DatHang ON tbl_DatHang AFTER INSERT AS 
    BEGIN
    	UPDATE tbl_KhoHang
    	SET SoLuongTon = SoLuongTon - (
    		SELECT SoLuongDat
    		FROM inserted
    		WHERE MaHang = tbl_KhoHang.MaHang
    	)
    	FROM tbl_KhoHang
    	JOIN inserted ON tbl_KhoHang.MaHang = inserted.MaHang
    END
    GO
    /* cập nhật hàng trong kho sau khi cập nhật đặt hàng */
    CREATE TRIGGER trg_CapNhatDatHang on tbl_DatHang after update AS
    BEGIN
       UPDATE tbl_KhoHang SET SoLuongTon = SoLuongTon -
    	   (SELECT SoLuongDat FROM inserted WHERE MaHang = tbl_KhoHang.MaHang) +
    	   (SELECT SoLuongDat FROM deleted WHERE MaHang = tbl_KhoHang.MaHang)
       FROM tbl_KhoHang 
       JOIN deleted ON tbl_KhoHang.MaHang = deleted.MaHang
    end
    GO
    /* cập nhật hàng trong kho sau khi hủy đặt hàng */
    create TRIGGER trg_HuyDatHang ON tbl_DatHang FOR DELETE AS 
    BEGIN
    	UPDATE tbl_KhoHang
    	SET SoLuongTon = SoLuongTon + (SELECT SoLuongDat FROM deleted WHERE MaHang = tbl_KhoHang.MaHang)
    	FROM tbl_KhoHang 
    	JOIN deleted ON tbl_KhoHang.MaHang = deleted.MaHang
    END
    
    

    Kết luận

    ?

    Việc mà bạn sử dụng Trigger là không bắt buộc và chúng ta thường tưởng rằng vì thế mà chả ai dùng nó là hoàn toàn sai . Nhưng Trigger theo như mình tìm hiểu qua thì vẫn có rất nhiều nơi sẽ sử dụng nó vào mục đích riêng của họ.

     
  • Hình đại diện của Không hiểu

    Viet nguyen van 5:30 pm on May 22, 2019 Liên kết tĩnh | Trả lời  

    Bài toán phân quyền vấn đề muôn thuở và rất khó hiểu. 

    (* Trong bài viết này mình chỉ nêu quan điểm và những thứ mình đã từng làm với việc phân quyền trên thực tế, chỉ mang tính tham khảo cho mọi người. Nếu có bất kỳ ý kiến góp ý nào hãy bình luận ở dưới để chúng ta cùng thảo luận thêm.)

    Phân quyền công việc mang đầy tính năng nề đối với dev nhưng lại đầy sáng tạo cho người dùng. Như bạn biết khi phần mềm được dựng lên là có vô vàn rắc rối xoay quanh quyền hạn người sử dụng, Vì thế lập trình viên đã tạo ra một thứ mang tên phân quyền để tránh tình trạng mọi người đều là vua trong chương trình đó đơn giản với việc “Bạn được quyền làm việc đó hay không?”.

    1. Phân quyền là gì?

    Tưởng tượng đơn giản như này nhé.

    • Bạn là sếp bạn có toàn quyền với nhân viên của mình
    • Bạn là trưởng phòng bạn chỉ có quyền với nhân viên trong phòng của mình
    • Bạn là trưởng nhóm dự án bạn chỉ có quyền với các thành viên trong nhóm
    • Và Nhóm < Phòng < công ty.
    • Như vậy bạn có thể thấy trong công ty này có 3 loại quyền hạn và chúng ta cần phân quyền theo nó

    2. Bạn thường dùng loại phân quyền như thế nào?

    • Câu hỏi này mình đặt ra ban đầu là “Có các loại phân quyền nào?” nhưng thật sự việc phân quyền này rất ít được public do nó mang tính chất riêng tư của những dự án. Nên nếu bạn search thì chủ yếu sẽ chỉ tìm được cách tạo tài khoản sử dụng cho user trong các HQTCSDL.
    • Ở bài viết này mình sẽ nói về việc phân quyền bằng nhóm quyền (Group) Và đưa ra 1 số cách dựng CSDL (db).

    3. Phân quyền theo group là gì và làm như thế nào ?

    • Phân quyền theo group là cách gọi chung của mình cho việc bạn nhóm nhiều thành viên trong 1 tổ chức có cùng một quyền hạn thực thi công việc. Lúc đó ta có thể nhóm họ vào 1 group để dễ dàng trao quyền hạn.
    • Như vậy từ cách phân quyền theo group này ta có thể sử dụng với “3 nấc” khác nhau.
    ?

    Ví dụ đơn giản về 3 cách này nhé  

    1. Phân quyền theo cấp bậc

    • Loại hình này chúng ta thường thiết kế db đơn giản như sau
    • Khi đó dữ liệu bạn dùng sẽ có dạng như thế này.
    • role ở đây là 1, 2, 3 tức là có 3 mức quyền hạn và lớn nhất hay bé nhất còn tùy thuộc vào quy định của mỗi công ty. Ví dụ
    – Ưu điểm

    Việc sử dụng kiểu phân quyền này dễ dàng cho những người mới bắt đầu. Những nhóm quyền được lập lên nhanh chóng có thể sử dụng luôn, Và việc phải check cũng tương đối là đơn giản, bạn chỉ cần 1 cần

    select count(*) from tbl_... where id = ? and role = ?
    hoặc
    select role from tbl_... where id = ?
    
    
    ?

    Rất dễ dàng để sử dụng đúng không. 

    – Nhược điểm

    Bạn biết đó việc sử dụng dữ liệu như này tồn tại 1 số nhược điểm rất lớn sau

    • Rất khó có thể mở rộng dự án
    • Trong thực tế không phải lúc nào cũng có 3 role. Nó có thể phát sinh nhiều role kì dị. Ví dụ: Thư ký giám đốc ngoài quyền đuổi việc ra còn lại nó sẽ có quyền của giám đốc vậy trường hợp này thuộc role 1 hay 2 ?.
    • Rất khó để phân quyền chi tiết.

    2. Phân quyền theo chức năng

    Loại phân quyền này được sử dụng rất nhiều trong thực tế. Nó rất hiệu quả và dễ thao tác đối với người cấp quyền.

    Ta thiết kế db đơn giản trong ví dụ này như sau:  Nhưng để Demo mình sẽ tóm gọn 2 bảng tbl_action và tbl_per_action thành bảng tbl_per_detail để dễ thao tác. Và ta có một Database như sau.  Chi tiết của việc thiết kế DB như sau:

    • tbl_user: bảng lưu người dùng bao gồm các thuộc tính như ID, Name,…. Bảng không có khóa ngoại.
    • tbl_permision: bảng chứa nhóm quyền hạn. bao gồm các thuộc tính, ID nhóm quyền hạn, tên nhóm quyền hạn.
    • tbl_permision_detail: là bảng sẽ chứa những quyền hạn cụ thể dành cho nhóm quyền hạn. Trường action_name không cần thiết bạn có thể bỏ. Trường action_code là để khi lập trình mình định nghĩa một thao tác nhất định trong bằng code này ví dụ quyền sửa thì code nó là EDIT chẳng hạn.
    • tbl_per_relationship: là bảng lưu mối liên hệ giữa người dùng và nhóm quyền hạn. Mục đích của bảng này không phải là để một người dùng có nhiều nhóm quyền mà để không phải truy vấn lại bảng user chứa thông tin nhạy cảm như username và password. Bạn cũng có thể bỏ qua bảng này và liên hệ trực tiếp giữa bảng user và permision luôn, nhưng mình khuyên bạn nên sử dụng thêm bảng này vì có nhiều trường hợp user có nhiều quyền hạn.

    1. Kiểm tra dữ liệu trong các bảng

    • tbl_user
    • tbl_permision
    • tbl_per_detail
    • tbl_user_per

    2. Làm một số ví dụ

    • Kiểm tra quyền của người dùng ví dụ: Hãy kiểm tra quyền của user có id là 1:
    DECLARE @result NVARCHAR(1000)
    SET @result = N\'Những quyền hiện tại của user (\'
    
    select @result = @result + name_user + \') là: \' from tbl_user where id_user = 1
    select @result = @result + action_name + \', \' from tbl_user as u
    	join tbl_user_per as up on u.id_user = up.id_user
    	join tbl_permision as p on up.id_per = p.id_per
    	join tbl_per_detail as pd on p.id_per = pd.id_per
    	where u.id_user = 1 and up.licensed = 1 and pd.check_action = 1
    select @result = substring(@result, 0, len(@result))
    
    print @result
    
    
    • kết quả
    • Kiểm tra xem user 2 có quyền xóa bài viết không ?
    DECLARE @result bit
    select @result = check_action from tbl_user as u
    	join tbl_user_per as up on u.id_user = up.id_user
    	join tbl_permision as p on up.id_per = p.id_per
    	join tbl_per_detail as pd on p.id_per = pd.id_per
    	where u.id_user = 2 and up.licensed = 1 and action_code = \'DELETE\'
    
    begin
    	if @result = 1
    		print N\'Bạn CÓ quyền xóa post\'
    	else
    		print N\'Bạn KHÔNG có quyền xóa post\'
    end
    
    
    • kết quả
    • Đó là một số ví dụ đơn giản tron tình huống này khi sử dụng phân quyền theo nhóm (group)

    3. Kết luận

    – Ưu điểm
    • Việc phân quyền này như mình có nêu ngay từ ban đầu rất dễ thao tác đối với những admin khi họ muốn chuyển nhóm quyền hoặc thỏa sức sáng tạo trong việc tạo ra những quyền mới từ những quyền ban đầu. Ví dụ như người dùng vừa có thể EDIT và DELETE,….
    • Ngoài ra việc thực hiện những câu querry cũng rất dễ dàng cho những lập trình viên.
    – Nhược điểm
    • Vấn đề sử dụng quyền hành động rất dễ khi chúng ta làm việc trên 1 group, nhưng nếu trong chương trình của bạn có nhiều group và phân cấp nhiều tầng thì nó lại là một vấn đề nan giải khác, khi bạn không chỉ phải check quyền hành động mà bạn còn phải check xem quyền hành động này của người dùng có thể áp dùng được trong group khác hay không?..

    3. Phân quyền theo Hành động của các nhóm Group theo những cấp bậc khác nhau

    • Đây là loại phân quyền lằng ngằng nhất nhưng lại là quan trọng nhất, bởi các lý do sau đây:
    • Các tổ chức sử dụng phần mềm để thực hiện thao tác của họ đều có phân cấp rõ ràng
    • Trong những tổ chức có những người nắm full quyền của nhiều nhóm
    • Có những thành viên thuộc nhiều nhóm
    • Có những thành viên tuy chỉ là nhân viên nhưng lại có quyền của các sếp (thư ký)
    • Chính vì có nhiều trường hợp như vậy những lập trình viên sinh ra được rất nhiều case trong code.

    Giải quyết vấn đề này bạn có thể tìm hiểu cách thự hiện phân quyền trong odoo.

    • Phân quyền theo model: Có nghĩ là người dùng được thao tác thực hiện với những bảng dữ liệu nào Ví dụ: Admin có thể thực hiện với thao tác với bảng user của họ
    • phân quyền theo raw: Người dùng được thực hiện việc thao tác với các raw được chỉ định Ví dụ: Leader A chỉ có thể thực hiện thao tác với những thành viên của mình trong bảng user
    • phân quyền theo column: Người dùng sẽ được quyền thao tac với nhưng column đó Ví dụ: Chỉ giám đốc mới có thể đuổi việc nhân viên, ở đây ta sẽ có 1 column tên là is_working để biết việc nhân viên đó còn đi làm hay không :D

    4. Kết luận

    • Việc bạn sử dụng cách nào hay thứ tự ra sao tưởng rằng không quan trọng nhưng nếu nhìn xa hơn trong việc mở rộng cũng như update phần mềm thì đó có thể là cực hình cho người sau.
    • Nếu bạn được quyền tham gia vào thiết kế database (thường là review và góp ý) thì hãy xem xét đến các vấn đề về việc những trường hợp phát sinh đề phòng những người tạo ra DB thiếu sót.
    ?

    Loại phân quyền thứ 3 có rất nhiều kiểu biến hóa trong từng phần mềm của từng công ty, Và mình sẽ cố gắng tìm hiểu thêm để viết một bài nói về kiểu này ngoài ra mình cũng sẽ cố gắng viết 1 bài nói về kiểu phân quyền của odoo. Thực chất nó cũng gần giống kiểu phân quyền trong group thôi . Cảm ơn các bạn đã đọc bài viết của mình. Văn phong hơi lủng củng nên mong các bạn thông cảm!.

     
  • Hình đại diện của Không hiểu

    Viet nguyen van 5:29 pm on May 22, 2019 Liên kết tĩnh | Trả lời  

    Quản lý ảnh trong cơ sở dữ liệu 

    • Trong lập trình chắc hẳn bạn đã đang hoặc sắp làm việc với dữ liệu ảnh  Nhưng cách lưu ảnh như nào cho hợp lý thì vẫn là những vấn đề mới mẻ và khó nhằn cho những bạn mới làm việc với dữ liệu. Bài viết này mình đưa ra các cách xây dựng dữ liệu sử dụng và truy vấn với hình ảnh đơn giản.
    • Có 2 kiểu lưu trữ ảnh riêng biệt đó là 1 ảnh được phục vụ cho một bảng và nhiều bảng.

    Một ảnh chỉ dùng cho một bảng

    Việc một ảnh chỉ dùng cho 1 bảng là việc phổ biến và thường xuyên với những hình ảnh riêng viết và đặc trưng như: logo, banner,… Những hình ảnh này được sử dụng nhiều nhưng số lượng lại rất ít và cần tốc độ lấy nhanh. 

    Ví dụ trên đây đơn giản là avata của người dùng. Câu lệnh lấy ảnh chỉ đơn giản như sau :

    SELECT * FROM avata WHERE user_id = ?
    
    
    • Ưu điểm : dễ sử dụng, thao tác nhanh chóng,…
    • Nhược điểm : Bạn chỉ có thể sử dụng 1 ảnh với 1 user.

    Một ảnh chỉ dùng cho nhiều bảng

    Có rất nhiều cách để thiết kế và sử dụng cho vấn đề này, ở đây mình đưa ra các cách thiết kế mà mình cho là lựa chọn tốt nhất đối với mọi người.

    1. Cách truyền thống

    Thiết dữ liệu theo dạng sau.  Sql query: 

    # Lấy avata của user có name là 'Tuan'
    select * from image where user_id = (select users.id from users where users.name = 'Tuan') and product_id is null
    # Đó là cách lấy thông thường của chúng ta. Nhưng cũng có thể viết ngắn gọn hơn bằng cách dùng join
    SELECT image.* FROM image	JOIN users on users.id = user_id where users.name = 'Tuan'
    #Tương tự ta có thể dùng cho products
    
    

    Kết quả. 

    • Ưu điểm : Cũng rất dễ dàng xử lý và thao tác.
    • Nhược điểm : Nhìn cũng đoán ra được Cách lưu ảnh kiểu này nếu chỉ có 1 2 bảng thì không sao, nhưng nếu có nhiều hoặc rất nhiều bảng dùng đến bảng image thì nó thật sự khủng khiếp khi ta liên tiếp phải thêm các trường (table)id.
    Từ đây chung ta sáng tạo ra một kiểu sau.

    2. Cách cải tiến từ truyền thống

    Thiết dữ liệu theo dạng sau. 

    • Chúng ta có thể nhận thấy thay vì thêm nhiều (table)_id thì ta chỉ cần 1 relation_id và type để thể hiện nó là hình ảnh của bảng nào.

    Sql query:

    -- Thử join bảng image và users vào xem kết quả thu được ra sao nhé 😀
    SELECT * FROM images JOIN users ON users.id = relation_id
    -- Còn đây là cách chúng ta thao tác để lấy ảnh của người dùng sử dùng type =))
    SELECT images.* FROM images
    join users on users.id = relation_id
    WHERE relation_id = 2 and type = 'user'
    
    

    Kết quả

    • Ưu điểm: Việc sử dụng cách thiết kế này giúp những nhà phát triển có thể dễ dàng mở rộng hệ thống, ngoài ra việc tạo các type giúp cho bạn linh động trong cách thực hiện hành vi của hệ thống.
    • Nhược điểm: Như bạn thấy đó ở cách 1 bạn có thể sử dụng hình ảnh từ users hoặc products. Nhưng đến cách 2 đây lại là nhược điểm năng nề nhất, việc sử dụng kiểu type này đã đã góp phần bắt buộc bạn nếu muốn 1 hình ảnh sử dụng trong nhiều bảng thì cũng đồng nghĩa bạn sẽ phải tạo ra thật nhiều row tương ứng.
    Từ đây những nhà phát triển tài năng lại sáng tạo ra một cách nữa các bạn có thể tham khảo nhé .

    3. Liệu những cách sau đây có là giải pháp thực thụ

    1. Cổ điểm theo phong cách mở rộng  
    • Với việc thêm 1 bảng trung gian using_images dễ dàng thấy đây là sự mở rộng của Cách 1 nhưng thay vì phải chỉnh sửa bảng (alterimages thì ta chỉ cần thêm cột vào bảng trung gian.
    1. Cải tiến mở rộng

     Khi bạn sử dụng cách này việc sử dụng using_type có thể giúp bạn tạo nhiều type khác nhau từ những bảng ban đầu. VD:

    idname
    1user
    2product
    3user, product

    Kết luận.

    • Việc bạn sử dụng những phương pháp để lưu trữ ảnh hay file nào thực chất nó không phải là bắt buộc phải làm như nào đối với mọi ứng dụng. Nhưng khi bạn thiết kế một cách thông minh và phù hợp với bài toán được đặt ra thì khi làm việc hết sức tiện lợi và nhanh chóng.
    • Ở bài viết trên mình không dám chắc những thiết kế của mình là hoàn toàn tối ưu và hay. Nhưng có một điều là nếu bạn là newbie và chưa có nhiều kinh nghiệm thì cách này sẽ giúp các bạn dễ hiểu hơn về hình thức lưu trữ ảnh cũng như luyện cách truy vấn thật tốt.
     
  • Hình đại diện của Không hiểu

    Viet nguyen van 5:28 pm on May 22, 2019 Liên kết tĩnh | Trả lời  

    Sự khác nhau cơ bản giữa MySql và SqlServer 

    Một ngày nào đó khi đang làm việc ngon lành với MySql và tưởng trừng cả cuộc đời là để dành chọn cho nó. Cũng trong ngày hôm đó khi project A của bạn đã và đang được really, công việc của bạn chỉ là ngồi xem phim và chờ mấy chị tét tờ lên danh sách bug, thì một tin nhắn được send thẳng đến bạn.

    ?

    A: T đang có project XXX này, nó làm bằng ABC..XYZ mày muốn đá thêm không  ?

    ?

    Me:  Cho xin cái lịch caffe.

    ?
    ?

    Không chần chừ đúng chuyên môn cộng thêm đây đang là thời gian rảnh của dự án vậy tội gì không đá thêm kiếm chút  gia tăng thu nhập . Sau khi caffe và bàn về dự án vs thằng bạn có một điều mãi mà bạn vẫn bẵn khoăn là: Tại sao khách hàng lại dùng MSSQL (SqlServer) nhỉ và đây là lý do bạn nhận được. 

    Tại khách hàng họ có server là windowns server 2012

    ?

    Vì đã có kiến thức nền tảng của Sql nên bạn không ngại khó lao vào tìm hiểu SqlServer với một niềm tin vững chắc chỉ cần 1 ngày là đủ .


    • Bỏ qua những vấn đề về việc install hay config bạn băng băng vào mớ lý thuyết hỗn độn để tìm điểm giống và khác nhau chủ yếu của 2 HQT này cuối cùng đúc kết ra được vài thứ nhỏ nhoi như sau.

    HQTCSDL đối lập nhau

    • Trong khi MySql có sẵn và miễn phí vì nó là là mã nguồn mở, nhưng SQLServer thì không. Bạn phải bỏ tiền ra và mua nó .
    • Ở MySql bạn có workbench giao diễn dễ nhìn trực quan, nhưng nó chả đáng là bao nếu so với Microsoft SQL Server Management Studio.
    • Về các function hay stored procedure ở SqlServer bạn được hỗ trợ nhiều hơn và họ cũng khuyến khích bạn dùng những thứ này hơn.

    Cú pháp khác nhau

    • Mình sẽ lấy vài ví dụ để cho bạn biết sự khác biệt của 2 HQT này ra sao.

    1. Những câu lệnh cơ bản

    • comment trong MySql và SqlServer bạn sẽ dùng  nhưng trong Mysql bạn phải thêm 1 khoảng trắng vào sau VD: -- select
    • Nối chuỗiMySql bạn dùng CONCAT(string, string2, …) còn SqlServer chỉ đơn giản là string + string2 + …
    • Số hàng bị ảnh hưởng của câu lệnh truy vấn
    --MySql
    SELECT .... ;
    SELECT FOUND_ROWS();
    
    -- SqlServer
    SELECT .... 
    GO
    SELECT @@ROWCOUNT
    
    

    2. Các kiểu dữ liệu tương đương

    Sql ServerMySql
    BITTINYINT
    FLOAT(p)DOUBLE
    SMALLMONEYDECIMAL(6,4)
    MONEYDECIMAL(15,4)
    NTEXTLONGTEXT
    NVARCHAR(max)LONGTEXT
    XMLLONGTEXT
    TEXTLONGTEXT
    IMAGELONGBLOB
    ROWVERSIONBINARY(8)
    TIMESTAMPBINARY(8)
    SMALLDATETIMEDATETIME

    3. Các hàm cơ bản thường dùng tương ứng

    Sql ServerMySql
    CONVERT(DATETIME, string, style)STR_TO_DATE(string, format)
    CONVERT(VARCHAR, datetime, style)DATE_FORMAT(datetime, format)
    DATEADD(unit, value, exp)TIMESTAMPADD(unit, value, exp)
    DATEDIFF(units, start, end)TIMESTAMPDIFF(units, start, end)
    GETDATE()NOW()
    GETUTCDATE()UTC_TIMESTAMP()
    HOST_NAME()@@HOSTNAME
    LEN(string)CHAR_LENGTH(RTRIM(string))
    STR(float, len, decimal)CONVERT(float, CHAR)

    4. Những câu query thần thánh

    • Limit--Trong MySql lấy 3 vị trí đầu tiên. Select * from tbl Limit 0,3 --Trong SqlServer lấy 3 vị trí đầu tiên. Select TOP 3 * from tbl
    • TriggerTrigger trong SqlServer và MySql có sự khác biệt cơ bản về cú pháp, nhưng ta chỉ cần nhớ 2 điều sau.INSERTED = NEWDELETED = OLDTừ đây ta có thể khởi tạo 1 trigger cơ bản ở 2 bên như sau:-- SqlServer CREATE TRIGGER trg_DatHang ON tbl_DatHang AFTER INSERT AS BEGIN UPDATE tbl_KhoHang SET SoLuongTon = SoLuongTon - ( SELECT SoLuongDat FROM inserted WHERE MaHang = tbl_KhoHang.MaHang ) FROM tbl_KhoHang JOIN inserted ON tbl_KhoHang.MaHang = inserted.MaHang END -- MySql CREATE TRIGGER trg_DatHang AFTER insert ON tbl_DatHang FOR EACH ROW BEGIN UPDATE tbl_KhoHang SET SoLuongTon = SoLuongTon - NEW.SoLuongDat where MaHang = New.MaHang; END;

    5. Các câu lệnh logic

    SqlServerMySql
    IF … ELSE IF …IF condition THEN … END IF;
    FLOAT(p)IF … ELSEIF …
    WHILE condition BEGIN stmts ENDWHILE condition DO stmts END WHILE;

    Kết luận

    • Đến đây nhiều người sẽ nghĩ rằng SqlServer tốt hơn MySql nhưng thực sự là không phải vậy. Tùy mục đích sử dụng hay những ngôn ngữ thường dùng mà bạn sẽ lựa chọn việc sử dụng HQT nào cho hợp lý.
    • Câu truyện trên là có thật nhưng vì một vài ví dụ so sánh ở dưới phần nhiều có lợi cho Sqlserver hơn nên mình quyết định đổi vế của nó để làm giảm bớt phần nào sự thiên vị. 
    • Bài viết trên chỉ là so sánh nho nhỏ giữa MySql và SqlServer, trên thực tế có rất nhiều HQT khác như Oracle, Informix, Postgres,… đó toàn là những RDMS (Relational Database Management System) nổi tiếng. Nên việc các developer phải sử dụng chúng là điều tất yếu. Nhưng nếu bạn nắm vững Sql căn bản hoặc ORM của các ngôn ngữ sử dụng thì vấn đề này không còn là khó khăn.

    Sự khác biệt giữa MySQL và SQL Server

    Sau đây, chúng tôi xin đưa ra bảng so sánh MySQL và SQL Server về tính năng, hiệu suất, bảo mật, khả năng nhân bản, khả năng phục hồi, phí tổn một cách ngắn gọn nhất giúp các bạn dễ theo dõi như sau:

    Đặc điểmMySQLSQL Server
    Tính năngCung cấp nhiều loại storage engine hơn.Intergate cho trọn bộ hệ thống và công cụ phát triển software chặt chẽ và tốt hơn.Ở mảng .NET. MSSQL còn hỗ trợ XML trực tiếp trong DB
    Hiệu suấtKhông đòi hỏi nhiều như SQL Server.Có thể chạy trên các UNIX highend system và perform tốt hơn SQL Server trên Windows highend server trong nhiều trường hợp.Perform kém hơn MySQL về nhiều mặt.Đòi hỏi tài nguyên rất lớn (CPU mạnh, nhiều RAM).
    Bảo mậtMySQL chỉ có thể set access đến row level là hết.Tính bảo mật cao hơn MySQL ở column level.Hệ thống xác thực cũng cao hơn, chặt chẽ hơn MySQL.Tuy nhiên, dễ bị exploit hơn MySQL.
    Khả năng nhân bản ( Replication)MySQL nhanh hơn và ít sự cố hơn SQL Server vì tất cả các SQL statements dùng để thay đổi, cập nhật dữ liệu được lưu giữ trong binary log.SQL Server cung cấp nhiều phương pháp replication cao cấp hơn, chi tiết hơn nên nó phức tạp và chậm hơn.
    Khả năng phục hồi ( Recovery)Nếu MySQL chạy với Innodb thì khả năng phục hồi không thua kém gì SQL Server.Nếu MySQL chạy thuần túy với MyISAM storage engine thì khả năng phục hồi (sau khi bị crash) không thể so sánh được với SQL Server.SQL phục hồi dễ dàng hơn.
    Phí tổnMySQL bản community không mất phí nhưng phải tự thủ công. Tuy nhiên, cài đặt, sử dụng và tối ưu MySQL không khó vì tài liệu về nó rất đầy đủ và nhiều có thể tìm thấy trên internet.Phải trả $1.5 cho một license SQL Server Standard và khi cần support, bạn phải trả thêm tiền support (tùy case). Bản enterprise thì phải trả tiền (khoảng $400) và bạn được support đầy đủ.SQL Server vẫn cung cấp bản miễn phí dành cho mục đích development.
     
  • Hình đại diện của Không hiểu

    Viet nguyen van 5:26 pm on May 22, 2019 Liên kết tĩnh | Trả lời  

    Một số kinh nghiệm khi optimize sql query 

    Thực ra thế này, tuần này mình optimize về phần API tìm kiếm và đến giờ vẫn chưa xong =)), và một số kinh nghiệm mình muốn chia sẽ khi optimize sql query.

    Sử dụng versioning và hậu quả

    GIới thiệu hoàn cảnh tí, về database của cái project đang làm thì nó lưu kiểu versioning (Giống như kiểu lưu history lại nhưng hiện tại nó lưu trong 1 table) nó có dạng như thế này:

    Create Table product.Products(
        ProductId BIGINT,
        VersionNumber INT,
        ProductName NVARCHAR(100),
        VersionComment NVARCHAR(100)
        ……
    ) 
    
    

    Đại loại là thế khi này cặp Key là (ProductId và VersionNumber) @@ khi làm việc hoặc lấy danh sách thì phải đi lấy thằng latest version, khi update thì nó lại insert thêm một dòng vào bảng đó.
    Dữ liệu nó sẽ hiển thị như thế này

    alt text

     

    Mới nhìn thôi cũng đã thấy củ chuối rồi hix hix, rất tiếc là structure này PO(ông là người Mỹ) đưa ra và product chạy được hơn 1 năm rồi, Vẫn chạy ngon lành, nhưng khi test dữ liệu lớn ( nó còn join các table đủ kiểu) thì nó đã die nhăn răng chạy không có ngày trở về..
    Cái đoạn lấy latest version kiểu như thế này:

     SELECT
                  pro.ProductId,
                  pro.VersionComment,
                  pro.VersionNumber,
                  pro.ProductName
    
           FROM product.Products pro 
           JOIN (SELECT pro.ProductId, MAX(pro.VersionNumber) AS LatestVersionNumber
                         FROM product.Products pro
                         GROUP BY pro.ProductId) productGroup ON pro.ProductId = productGroup.ProductId
           WHERE pro.VersionNumber = productGroup.LatestVersionNumber
    
    

    Các phương pháp sử dụng with CTE đã sử dụng performance thì nó cũng ngang ngang nhau

    Và để giải quyết trường hợp này thì mình có 2 solution :

    • Thêm một field IsLatestVersion dòng nào là latest version thì cho nó = true. Đã test và chạy nhanh đáng kể, nhưng database trên bảng truy vấn nó vẫn nhiều nhưng không sao vẫn chấp nhận được
    • Tách table, thêm một table histories và 1 table thì lưu giữ giá trị của latest version. Khi đó database truy vấn sẽ được giảm đáng kể, thấy ok rồi đó, chạy ngon cành đào ^^ , mất mấy giây để lấy dữ liệu.

    Ngon ngon nhưng 2 giải pháp này đêu không được chấp nhận vì nó impact rất nhiều tới các method của API. Việc test lại toàn bộ API không hề đơn giản sẽ rất là lâu cho dù là đang sử dụng automation test….

    Hix hix đến dây vấn đề vẫn đang bị tắc và giải pháp đưa ra cho vấn đề này là đưa ra con số chính xác bao nhiêu dữ liệu thì nó sẽ bị time out khi query. Nếu mà nó ít hơn hoặc xấp xỉ dữ liệu trên Production thì khi đó tính tiếp :v :v.

    Không nên dùng nhiều bảng tạm khi truy vấn

    Hiện tại câu query này được build dựa trên parameters truyền vào(filter, sort, results) tức là build sql dynamic. Và câu query xử lí rất nhiều trường hợp nên phải sử dụng bảng tạm để lưu lại kết quả hix hix đây có lẽ là một sai lầm ngớ ngẫn nhất khi dùng bảng tạm trong việc query với dữ liệu lớn. Trong query cũ thì có dùng 2 table tạm, và việc chạy dữ liệu nhiều nó đã góp phần làm chậm câu query. Khi mình đo performance thì việc insert và 2 bảng tạm đó 1 cái chiếm đến 50% còn cái còn lại chiếm đến 99% (vì có 2 câu query) @@ oa oa, và việc đầu tiên xóa bảng tạm ngay lập tức, bằng việc dùng subquery và tính toán một số cái trên câu lệnh select.
    Kiểu dạng này :

     Select a,b,c ,d = a +b, ..
     From(
        Select a,b,c
        From table1
        where...
     )
     Where a = 1
    
    

    Từ hơn 15p để query ra đống dữ liệu và nó đã xuống còn mấy giây. 
    2 câu bảng tạm nó có dạng như thế này:
    Câu thứ 1:

    DELACRE @tmpTable TABLE (Id INT, Name NVARCHAR(100));
    INSERT INTO @tmpTABLE SELECT Id,Name FROM RealTable WHERE ….
    
    

    Câu thứ 2:

    SELECT Id,Name 
    INTO #tmp 
    FROM  product.Products pro
    INNER JOIN @tmpTable….
    LEFT JOIN .....
    
    

    Ở đây mình sử dụng 2 bảng tạm @tmpTable và #tmp và mình đo performance thì khi insert vào #tmp thì chiếm tới 99% thời gian >.<

    Do câu query thực nó rất phức tạp với lại tính security của data nên mình không nêu cụ thể lên. Nó còn một số vấn đề nữa nhưng không tiện post lên.

     
  • Hình đại diện của Không hiểu

    Viet nguyen van 11:55 am on May 22, 2019 Liên kết tĩnh | Trả lời
    Tags: Iphone, Siri   

    Tiện ích tuyệt vời của Siri trên iPhone! 

    Đặt báo thức

    「明日の6時に起こして」 (hãy đánh thức tôi vào lúc 6h ngày mai) Okoshite
    「7時間後に起こして」 (hãy đánh thức tôi sau 7h)
    「8時にアラームをセットして」 (hãy hẹn báo thức vào lúc 8h)

    * Wake me up in 8 hours
    * Change my 6:30 alarm to 6:45
    * Turn off my 6:30 alarm
    * Delete my 7:30 alarm
    -4.2: Kiểm tra thời gian
    * What time is it?
    * What time is it in Berlin?
    * What is today’s date?
    * What’s the date this Saturday?
    -4.3 : Sử dụng chức năng Timer
    * Set the timer for ten minutes
    * Show the timer
    * Pause the timer
    * Resume
    * Reset the timer
    * Stop it

    Tính toán

    「27300円を10人で割り勘」 (chia 27300 yên cho 10 người)  (warikan )

    Chỉ dẫn đường (navigation)

    Thay vì mở ứng dụng Map và tỉ mẩn gõ địa chỉ cần tra, bạn chỉ cần đọc nơi muốn đến và Siri sẽ chỉ dẫn chi tiết cho bạn.
    Với những câu mệnh lệnh đơn giản, Siri sẽ nhận thông tin dễ dàng hơn, ví dụ như:

    「電車を使って上野駅から新宿まで」 (Từ ga Ueno đến Shinjuku bằng tàu điện)
    「新宿駅までナビして」 (hãy chỉ đường tới ga Shijuku)

    Nghe nhạc

    「(アーティスト名)を流して」 (hãy phát bài hát..)
    「(曲名)を流して」 (hãy phát bản nhạc..)

    Điều này đặc biệt tiện dụng khi bạn tập thể dục, chạy bộ, nấu ăn… không rảnh tay để chuyển bài hát.

    Danh bạ
    * What’s Michael’s address? : Hỏi về địa chỉ 
    * What is Susan Park’s phone number? : Hỏi về SĐT
    * When is my wife’s birthday? : Hỏi về ngày sinh
    * Show Jennifer’s home email address : Hỏi về địa chỉ Mail.

    * Show Jason Russell : Kiểm tra thông tin
    * Find people named Park : Tìm tên trong danh bạ
    * Who is Michael Manning? : Tìm tên trong danh bạ

    2. Gán các mối quan hệ: Các bạn tự gán nhé 
    * My mom is Susan Park 
    * Michael Manning is my brother
    * Call my brother at work

    3. Lịch:
    -3.1 : Sự kiện:
    * Set up a meeting at 9 : Đặt lịch họp
    * Set up a meeting with Michael at 9 : nt
    * Meet with Lisa at noon : đặt lịch hẹn
    * Set up a meeting about hiring tomorrow at 9am
    * New appointment with Susan Park Friday at 3
    * Schedule a planning meeting at 8:30 today in the boardroom
    -3.2 : Thay đổi sự kiện
    * Move my 3pm meeting to 4:30
    * Reschedule my appointment with Dr. Manning to next Monday at 9am
    * Add Lisa to my meeting with Jason
    * Cancel the budget review meeting
    -3.3 : Hỏi về lịch 
    * What does the rest of my day look like?
    * What’s on my calendar for Friday?
    * When is my next appointment?
    * When am I meeting with Michael?
    * Where is my next meeting?

    5. Email:
    -5.1: Gửi mail:
    * Email Lisa about the trip
    * Email Jennifer about the change in plans
    * New email to Susan Park
    * Mail Dad about the rent check
    * Email Dr. Manning and say I got the forms, thanks
    * Mail Lisa and Jason about the party and say I had a great time
    -5.2: Kiểm tra mail:
    * Check email
    * Any new email from Michael today?
    * Show new mail about the lease
    * Show the email from Lisa yesterday

    6. Tra cứu về bạn bè:
    * Where’s Jason? : Vị trí của bạn 
    * Where is my sister? : Hỏi về vị trí bạn
    * Is my wife at home? : Tra vợ 

    ;)

    )
    * Where are all my friends?
    * Who is here?
    * Who is near me? : Xem ai ở gần mình

    7. Bản đồ:
    * How do I get home? : Tìm đường về nhà どうやって家に帰るの?
    * Directions to my dad’s work : Chỉ đường đến địa điểm
    * Find coffee near me
    * Where is Starbucks?
    * Find some burger joints in Baltimore
    * Find a gas station within walking distance
    * Good Mexican restaurants around here

    8. Tin nhắn :
    -8.1: Gửi tin nhắn: Bạn có thể thêm lời nhắn, dùng Eng nhé
    * Tell Susan I’ll be right there
    * Send a message to Jason Russell
    * Send a message to Lisa saying how about tomorrow
    * Tell Jennifer the show was great
    * Send a message to Susan on her mobile saying I’ll be late
    * Send a message to 408 555 1212
    * Text Jason and Lisa where are you?
    -8.2 : Đọc tin nhắn :
    * Read my new messages : Đọc tin nhắn mới nhất
    * Read it again : Đọc lại
    -8.3: Trả lời :
    * Reply + “that’s great news”
    * Tell him I’ll be there in 10 minutes
    * Call her

    9. Trình phát nhạc
    :
    * Play The Light of the Sun : play + tên bài hát
    * Shuffle my roadtrip playlist
    * Play : Phát
    * Pause : Dừng
    * Skip : Bỏ qua

    10. Gọi điện thoại:
    * Call Jason
    * Call Jennifer Wright mobile
    * Call Susan on her work phone
    * Call 408 555 1212
    * Call home
    * FaceTime Lisa : Sử dụng FT

    11. Ứng dụng Reminders:
    * Remind me to call mom
    * Remind me to call my mom when I get home
    * Remember to take an umbrella
    * Remind me take my medicine at 6am tomorrow
    * Remind me to pick up flowers when I leave here
    * Remind me when I leave to call Jason
    * Remind me to finish the report by 6

    12. Thời tiết :
    * What’s the weather for today?
    * What’s the weather for tomorrow?
    * Will it rain in Cupertino this week?
    * Check next week’s forecast for Burlington
    * What’s the temperature outside?
    外の気温は?
    * When is sunrise in Paris?

    13. Tìm kiếm thông tin trực tuyến
     :

    Sử dụng Google, Bing, Search ở đầu mỗi từ khóa cần tìm: * Search the web for Bora Bora グーグル

     
  • Hình đại diện của Không hiểu

    Viet nguyen van 11:02 am on May 22, 2019 Liên kết tĩnh | Trả lời  

    SQL 

    Đăng nhập cơ sở dữ liệu bằng T-SQL Script

    Để tạo tên đăng nhập là TestLogin và mật khẩu là P@ssword, bạn chỉ cần chạy 2 truy vấn dưới đây.

    Create login yourloginname with password='yourpassword'
    
    Create login TestLogin with password='P@ssword'
    
     
c
Compose new post
j
Next post/Next comment
k
Previous post/Previous comment
r
Trả lời
e
Sửa
o
Show/Hide comments
t
Chuyển lên trên
l
Go to login
h
Show/Hide help
shift + esc
Hủy bỏ
Tạo trang giống vầy với WordPress.com
Hãy bắt đầu