Trang 2 / 2 FirstFirst 12
Hiển thị kết quả từ 11 đến 15 / 15
  1. #11
    Tham gia
    23-01-2005
    Location
    http://hoctudau.com
    Bài viết
    2,957
    Like
    105
    Thanked 365 Times in 209 Posts
    Cái này search cuốn sách : SQL Anti Pattern nhé, tiếng Anh, nói khá chi tiết.
    Thông tin + clip: http://youtube.com/hoctudau

  2. #12
    Tham gia
    01-07-2010
    Bài viết
    56
    Like
    0
    Thanked 0 Times in 0 Posts
    Cái này thì dùng ID với đệ quy là đúng rồi. Còn khi search thì tìm tất cả ID rồi mới search. Theo m là vậy. hi

  3. #13
    Tham gia
    23-01-2005
    Location
    http://hoctudau.com
    Bài viết
    2,957
    Like
    105
    Thanked 365 Times in 209 Posts
    Quote Được gửi bởi tinhtoi View Post
    Cả hai cách mình đều đã làm thử và đều thành công, nhưng cách nào cũng phải dùng đệ quy để xử lý. Như bạn nói, cách một thì truy vấn quá nhiều, còn cách hai thì truy vấn dư thừa dữ liệu. Vì vậy mình mới lập topic này để mọi người cùng vào thảo luận nhằm tìm ra phuơng pháp tối ưu cho vấn đề trên.
    được cái này mất cái nọ thôi, ko có cách tối ưu, nếu lười đọc sách thì đọc tạm link này:

    http://articles.sitepoint.com/articl...-data-database

    Cách sau có lẽ bạn thích:


    cách này thì khi insert hơi mệt, còn select thì 1 query thôi.
    Thông tin + clip: http://youtube.com/hoctudau

  4. #14
    Tham gia
    20-07-2009
    Location
    Hà Nội
    Bài viết
    125
    Like
    0
    Thanked 8 Times in 8 Posts
    Nếu mình không nhầm thì cách duyệt cây mà bạn đưa ra là 1 trong 3 cách duyệt cây cơ bản: Duyệt theo thứ tự trước, sau và giữa

    Bất kì một SV CNTT nào cũng phải học qua rồi. Cá nhân tôi thì cho rằng, không phải cứ áp thuật toán , rồi diễn giải nó bằng SQL cho DB là tốt.

  5. #15
    Tham gia
    20-02-2009
    Location
    Ninh Bình
    Bài viết
    567
    Like
    0
    Thanked 34 Times in 31 Posts
    Quote Được gửi bởi tinhtoi View Post
    Có hai trường hợp:
    1.Nếu không có map: bạn không thể xác định một nhánh trong cây mà phải lấy ra cả cây => dư thừa.
    2.Có map: khi cập nhật phải xác định map cho một nhánh, mà cái này cũng phải dùng đệ quy để xác định => rắc rối như khi search. Trường hợp kết chuyển nhiều thứ thì cập nhật dữ liệu sẽ rất chậm.

    Mình không rành về store lắm nên không viết được T-SQL, bạn thông cảm. mình xử lý bằng code.

    [=========> Bổ sung bài viết <=========]

    Hàm đệ quy nè bạn:
    Sub layNVTheoNode(ByVal NhanVienID As String, ByVal arr As ArrayList)
    arr.Add(NhanVienID )
    Dim ds As New DataSet
    If Lay_SQL_P(ds, "select NhanVienID from NhanVien where NhanVienCha=@NhanVienCha", NhanVienID ) = True Then
    If ds.Tables(0).Rows.Count > 0 Then
    For Each drw As DataRow In ds.Tables(0).Rows
    layNVTheoNode(drw("NhanVienID").ToString, arr)
    Next
    End If
    End If
    End Sub

    [=========> Bổ sung bài viết <=========]

    Nói chung mình thấy chưa được hay lắm
    Vấn đề là mỗi lần hàm đệ quy trên được gọi, nó kết nối với CSDL để lấy về danh sách của những nhân viên dưới quyền. Như thế, hàm đệ quy có thể phải truy vấn CSDL cả hàng trăm, hàng ngàn lần tùy theo kích thước và mức độ phân quyền. Thành thử ra, dở là cái chắc.

    Hôm nay đã khuya. Thôi hẹn ngày mai tôi sẽ đưa lên cách dùng giải thuật đệ quy trong CSDL để giải quyết vấn đề bạn đã đưa ra.

    **** Tiếp tục..

    Đệ quy là danh từ được dịch qua tiếng Việt từ chữ recursive, có nghĩa là một vòng tự lặp.

    Khi thiết kế một CSDL, đôi khi các bạn sẽ có nhu cầu cần phải tạo lên một bảng đệ quy. Bảng đệ quy là một bảng có khoá ngoại liên kết với khoá chính của chính nó, thí dụ như bảng NHAN_VIEN dưới đây, có khoá ngoại cho ma_truong_nhom liên kết với ma_nhan_vien:

    Code:
    IF NOT EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[NHAN_VIEN]') AND OBJECTPROPERTY(id, N'IsUserTable') = 1)
    BEGIN
        CREATE TABLE dbo.NHAN_VIEN
        (
            ma_nhan_vien UNIQUEIDENTIFIER NOT NULL DEFAULT(NEWID()),
            ma_truong_nhom UNIQUEIDENTIFIER NULL,
            ma_chuc_vu UNIQUEIDENTIFIER NOT NULL,
            ma_luong UNIQUEIDENTIFIER NOT NULL,
            CONSTRAINT PK_NHAN_VIEN PRIMARY KEY
            (
                ma_nhan_vien
            ),
            CONSTRAINT FK_NHAN_VIEN_ma_truong_nhom FOREIGN KEY
            (
                ma_truong_nhom
            )REFERENCES [dbo].[NHAN_VIEN](ma_nhan_vien) -- Recursive (tự liên kết)
        )
    END
    GO
    Khi các bạn đã có một bảng đệ quy rồi, thì việc dùng Bảng Giải thuật Thông dụng (Common Table Expression - CTE) để truy vấn và lấy về một tập hợp dữ liệu được phân cấp rất dễ dàng. Xin lưu ý là với Bảng Giải thuật Thông Dụng (BGT), các bạn không cần phải có một bảng đệ quy mà vẫn có thể truy vấn và lấy về một tập hợp dữ liệu được phân cấp.

    Dưới đây là stored procedure isp_truy_van_nhan_vien:
    Code:
    IF EXISTS(SELECT 1 FROM sysobjects WHERE id = OBJECT_ID('dbo.isp_truy_van_nhan_vien')
    										AND OBJECTPROPERTY(id,N'IsProcedure') = 1
    		  )
    BEGIN
    	DROP PROCEDURE dbo.isp_truy_van_nhan_vien
    END 
    GO
    
    CREATE PROC dbo.isp_truy_van_nhan_vien
    --WITH ENCRYPTION
    AS
    BEGIN
    	SET NOCOUNT ON
    
    	WITH CTE_NHAN_VIEN (ma_nhan_vien,ma_truong_nhom,ma_chuc_vu,ma_luong, phan_cap) AS
    	(
    	   -- truy vấn cấp cao nhất
    	   SELECT
    		  ma_nhan_vien,
    		  ma_truong_nhom,
    		  ma_chuc_vu,
    		  ma_luong,
    		  1 as phan_cap
    	   FROM NHAN_VIEN(NOLOCK)
    	   WHERE ma_truong_nhom IS NULL
    
    	   UNION ALL
    
    	   -- vòng lặp đệ quy
    	   SELECT
    
    			NV.ma_nhan_vien,
    			NV.ma_truong_nhom,
    			NV.ma_chuc_vu,
    			NV.ma_luong,
    			CTE.phan_cap + 1 as phan_cap
    	   FROM NHAN_VIEN NV (NOLOCK)
    		  INNER JOIN CTE_NHAN_VIEN CTE
    			 ON(CTE.ma_nhan_vien = NV.ma_truong_nhom)
             
    	)
    
            -- Và sau cùng, lấy về tất cả những bản ghi đã được đưa vào bảng biểu thức thông dụng
    	SELECT *
    		FROM CTE_NHAN_VIEN
    		ORDER BY phan_cap
    END
    GO
    Với stored procedure trên, các bạn chỉ cần truy vấn từ CSDL một lần duy nhất là có một tập hợp những bản ghi của nhân viên được phân cấp.

    Tưởng cũng nên nói thêm rằng, BGT không phải chỉ dành riêng cho đệ quy, mà chỉ là một công cụ rất tốt cho đệ quy. Các bạn có thể dùng BGT trong bất cứ một trường hợp nào cần dùng đến bảng nhớ tạm thời (MEMORY TABLE).
    Được sửa bởi dq_ninh lúc 00:20 ngày 16-08-2010 Reason: Bổ sung bài viết

  6. Thành viên Like bài viết này:


Trang 2 / 2 FirstFirst 12

Bookmarks

Quy định

  • Bạn không thể tạo chủ đề mới
  • Bạn không thể trả lời bài viết
  • Bạn không thể gửi file đính kèm
  • Bạn không thể sửa bài viết của mình
  •