2008-10-01 31 views
7

Tôi cần lời khuyên về cách xử lý các nhóm cờ tương đối lớn trong bảng SQL2k8 của tôi.Cách xử lý nhiều cờ cho bản ghi SQL

Hai câu hỏi, hãy liên hệ với tôi, vui lòng :)

Giả sử tôi có 20 lá cờ tôi muốn lưu trữ một bản ghi.

Ví dụ:

CanRead = 0x1 CanWrite = 0x2 CanModify = 0x4 ... và vân vân để lá cờ chính thức 2^20

Bây giờ, nếu tôi đặt sự kết hợp sau đây một bản ghi: Quyền = CanRead | CanWrite

tôi có thể dễ dàng kiểm tra xem kỷ lục đó đã yêu cầu sự cho phép bằng cách làm WHERE (Quyền & CanRead) = CanRead

đó làm việc.

Nhưng, tôi cũng muốn truy xuất tất cả các bản ghi có thể viết hoặc sửa đổi.

Nếu tôi phát hành WHERE (Quyền & (CanWrite | CanModify)) = (CanWrite | CanModify) tôi rõ ràng sẽ không nhận được hồ sơ của tôi có quyền được đặt thành CanRead | CanWrite

Nói cách khác, làm cách nào tôi có thể tìm thấy các bản ghi khớp với BẤT K of cờ trong mặt nạ mà tôi đang gửi đến quy trình?

Câu hỏi thứ hai, hiệu suất hoạt động trong SQL 2008 như thế nào? Nó sẽ thực sự tốt hơn để tạo ra 20 trường bit?

Nhờ sự giúp đỡ của bạn

Trả lời

6

gì về

WHERE (Permissions & CanWrite) = CanWrite 
OR (Permissions & CanModify) = CanModify 

?

3

WHERE (Quyền & CanWrite) = CanWrite OR (Quyền & CanModify) = CanModify

Tôi nghĩ

1

Nó muốn được tốt hơn đáng kể để có một mô hình cấp phép khác nhau.

20 cờ sẽ cho tôi biết rằng cần phải xem xét lại, hầu hết các hệ thống có thể nhận được 12 cờ cơ bản và ACLS - có thể có bảng riêng chỉ cấp quyền hoặc nhóm đối tượng hoặc người truy cập để cho phép điều khiển khác nhau.

Tôi hy vọng một lựa chọn sẽ nhanh hơn để có 20 trường riêng biệt - nhưng tôi cũng sẽ không thêm 20 trường cho hiệu suất.

--UPDATE--

các truy vấn ban đầu được viết như

WHERE (Permissions & (CanWrite | CanModify)) > 0 

sẽ là đủ, tuy nhiên nó có vẻ là như những gì bạn có trong cơ sở dữ liệu là một tập hợp các thuộc tính rằng một thực thể có thể có.Trong trường hợp này, chỉ có một cách hợp lý (trong thuật ngữ cơ sở dữ liệu) để làm điều này là với mối quan hệ một-nhiều với một bảng thuộc tính.

0

Không, điều đó sẽ không hoạt động.

tôi gửi chỉ là một mặt nạ để các thủ tục

Something như @filter mà trong C# i đầy @filter = CanModify | CanWrite

Vì vậy, quy trình sẽ nhận giá trị OR-ed làm bộ lọc.

Ồ, nhân tiện, nó KHÔNG phải là mô hình cho phép, tôi đang sử dụng nó như một ví dụ.

Tôi thực sự có khoảng 20 cờ duy nhất mà đối tượng của tôi có thể có.

3

Không phải là nó đơn giản như ...

WHERE (Permissions & (CanWrite | CanModify)) > 0 

... như bất kỳ 'chút' được thiết lập để 1 sẽ dẫn đến một giá trị khác không cho '&' điều hành.

Đó là vào cuối ngày và tôi sắp về nhà, vì vậy bộ não của tôi có thể hoạt động kém hiệu quả.

11

Đừng làm vậy. Giống như lưu chuỗi CSV vào trường ghi nhớ và đánh bại mục đích của cơ sở dữ liệu.

Sử dụng giá trị boolean (bit) cho mỗi cờ. Trong ví dụ cụ thể này, bạn đang tìm mọi thứ có thể đọc và có thể viết hoặc sửa đổi:

WHERE CanRead AND (CanWrite OR CanModify) 

SQL thuần túy đơn giản không có hack thông minh. 7 bit thêm của bạn đang lãng phí cho mỗi lá cờ không phải là giá trị đau đầu.

+0

-1 vì lôgic VÀ/HOẶC không giống như bitwise &/|. –

+2

Đó là nếu như áp phích được đề xuất, mỗi trường chỉ có một bit. –

+0

Lấy ví dụ này là một ví dụ về mệnh đề where đơn giản, tất cả những gì bạn cần khi xử lý các giá trị bit. Ý định của tôi là không tái tạo một truy vấn cụ thể. – VVS

12

Tôi giả sử cột Quyền của bạn là Int. Nếu có, tôi khuyến khích bạn chơi xung quanh với mã mẫu mà tôi cung cấp bên dưới. Điều này sẽ cho bạn một dấu hiệu rõ ràng về cách thức hoạt động của chức năng.

Declare @Temp Table(Permission Int, PermissionType VarChar(20)) 

Declare @CanRead Int 
Declare @CanWrite Int 
Declare @CanModify Int 

Select @CanRead = 1, @CanWrite = 2, @CanModify = 4 

Insert Into @Temp Values(@CanRead | @CanWrite, 'Read,write') 
Insert Into @Temp Values(@CanRead, 'Read') 
Insert Into @Temp Values(@CanWrite, 'Write') 
Insert Into @Temp Values(@CanModify | @CanWrite, 'Modify, write') 
Insert Into @Temp Values(@CanModify, 'Modify') 

Select * 
From @Temp 
Where Permission & (@CanRead | @CanWrite) > 0 

Select * 
From @Temp 
Where Permission & (@CanRead | @CanModify) > 0 

Khi bạn sử dụng hợp lý và bạn sẽ nhận được số có tập hợp số 1 phù hợp dựa trên điều kiện của bạn. Nếu không có gì phù hợp, kết quả sẽ là 0. Nếu 1 hoặc nhiều điều kiện phù hợp, kết quả sẽ lớn hơn 0.

Hãy để tôi chỉ cho bạn một ví dụ.

Giả sử CanRead = 1, CanWrite = 2, và CanModify = 4. kết hợp hợp lệ là:

Modify Write Read Permissions 
------ ----- ---- ----------- 
    0  0 0 Nothing 
    0  0 1 Read 
    0  1 0 Write 
    0  1 1 Read, Write 
    1  0 0 Modify 
    1  0 1 Modify, Read 
    1  1 0 Modify, Write 
    1  1 1 Modify, Write, Read 

Bây giờ, giả sử bạn muốn kiểm tra cho đọc hoặc sửa đổi. Từ ứng dụng của bạn, bạn sẽ chuyển sang (CanRead | CanModify). Điều này sẽ là 101 (theo dạng nhị phân).

Trước tiên, hãy kiểm tra điều này với một hàng trong bảng mà ONLY đã đọc.

001 (Row from table) 
& 101 (Permissions to test) 
------ 
    001 (result is greater than 0) 

Bây giờ, hãy thử nghiệm với hàng chỉ ghi.

010 (Row from table) 
& 101 (Permission to test) 
------ 
    000 (result = 0) 

Bây giờ hãy thử nghiệm nó với hàng có tất cả 3 quyền.

111 (Row from table) 
& 101 (Permission to test) 
------ 
    101 (result is greater than 0) 

Tôi hy vọng bạn có thể thấy rằng kết quả của phép toán AND mang lại giá trị = 0, thì không có quyền kiểm tra nào áp dụng cho hàng đó. Nếu giá trị lớn hơn 0, thì có ít nhất một hàng.

0

Chỉ thực hiện việc này nếu bạn cũng đang truy vấn bằng một số khóa khác.

Đừng làm điều này nếu bạn đang truy vấn bằng cách kết hợp cờ. Một chỉ số chống lại cột này sẽ không giúp bạn nói chung. Bạn sẽ bị hạn chế để quét bảng.

Các vấn đề liên quan