Trong khi các nhà điều hành Bitwise đề xuất bởi James sẽ làm việc, nó sẽ không thể rất biểu diễn trong cơ sở dữ liệu quan hệ, đặc biệt khi bạn cố gắng mở rộng tới hàng triệu bản ghi. Lý do là các hàm trong mệnh đề where không được sargable (chúng ngăn cản chỉ mục tìm kiếm).
Điều tôi sẽ làm là tạo một bảng chứa tất cả các kết hợp cờ và điều kiện có thể có, điều này sẽ cho phép chỉ mục tìm kiếm điều kiện.
Populate FlagConditions. Tôi đã sử dụng một đơn (tinyint). bạn nên cần thêm Flags, bạn sẽ có thể mở rộng tiếp cận này:
CREATE TABLE FlagConditions (
Flag TINYINT
, Condition TINYINT
, CONSTRAINT Flag_Condition PRIMARY KEY CLUSTERED (Condition,Flag)
);
CREATE TABLE #Flags (
Flag TINYINT IDENTITY(0,1) PRIMARY KEY CLUSTERED
, DummyColumn BIT NULL);
GO
INSERT #Flags
(DummyColumn)
SELECT NULL;
GO 256
CREATE TABLE #Conditions(Condition TINYINT PRIMARY KEY CLUSTERED);
INSERT #Conditions (Condition)
VALUES (1),(2),(4),(8),(16),(32),(64),(128);
INSERT FlagConditions (Flag, Condition)
SELECT
Flag, Flag & Condition
FROM #Flags f
CROSS JOIN #Conditions c
WHERE Flag & Condition <> 0;
DROP TABLE #Flags;
DROP TABLE #Conditions;
Bây giờ bạn có thể sử dụng bảng FlagConditions bất cứ lúc nào bạn cần phải tìm kiếm hiệu quả trên một điều kiện enum Bitwise:
DECLARE @UserFlags TABLE (Username varchar(10), Flag tinyint);
INSERT @UserFlags(Username, Flag)
VALUES ('User1',6),('User2',4),('User3',14);
DECLARE @Condition TINYINT = 2;
SELECT u.*
FROM @UserFlags u
INNER JOIN FlagConditions fc ON u.Flag = fc.Flag
WHERE fc.Condition = @Condition;
Điều này trả về:
Username Flag
---------- ----
User1 6
User3 14
DBA của bạn sẽ cảm ơn bạn đã thực hiện tuyến đường được định hướng này.
Nó sẽ được nhiều hơn "SQL-like" để lưu trữ này thông tin trong một bảng nhiều người. Vì vậy, bạn sẽ lưu trữ các hàng '(1,1), (1,2), (2,2), (3,1), (3,2), (3,3)' trong một bảng riêng biệt. Nó sẽ làm cho truy vấn tự nhiên hơn, và cung cấp các cơ hội lập chỉ mục. –