2012-08-02 15 views

回答

7

您的問題的答案是「否」。位字段會犧牲關係完整性,原因很簡單,您的數據庫中沒有相應表的實體。

也就是說,許多數據庫通常通過「比特」數據類型提供對此的支持。 Mysql有更強大的支持,具有「set」數據類型。

主要問題是您不知道集合中的元素 - 什麼是全名,什麼時候被添加到數據庫中,等等。 (枚舉繞過命名問題的一部分。)另外,集合的大小是有限的。你可能有一個事例有限的例子。但是,馬特的例子更強調這裏的問題。你可以有一個大陸訪問的列表。但是,當你轉向訪問的國家時,這種做法必然會有很大的不同,因爲國家的數量不再適合一個「單詞」。你想讓你的系統在這方面與各國大不相同嗎?你是否希望你的設計決定受計算機單詞中32位或64位的限制?

最後,你似乎認爲表的擴散是一個問題。表格的擴散實際上是一種解決方案。所有有關實體的數據都存儲在表中,而不是通過系統分散。您可以維護關於實體實例的信息,例如創建實例的時間,它可能隨時間變化的方式等等。每當有人想要一個大陸時,可能會使用「大洲」實體。

考慮一下系統中發生了什麼,兩個不同的開發人員決定爲大陸開發自己的位掩碼 - 但他們將大陸按不同的順序排列。通過設計良好的關係數據庫(意味着在表定義中明確聲明瞭外鍵關係),就不會出現這種混淆。

+1

我同意。我想補充一點,您可能會通過自己動手的按位字段方法損失查詢清晰度。清晰簡潔在非平凡系統中非常重要。 – smv 2012-08-02 18:21:37

9

對於一對多關係,其中「many」具有少量已知值,可以將關係作爲整數作爲位掩碼存儲在父表中,取代了對額外表的需要。

假設我們有一個表Person,我們想知道一個人訪問過多少個大陸。我們首先將每個Continent分配一個「正交」位值。在C#中,枚舉是一個不錯的選擇:

[Flags] 
public enum JobAdvertisingRegion 
{ 
    NorthAmerica = 1,    // or 1 << 0 
    SouthAmerica = 2,    // 1 << 1 
    Europe = 4,     // 1 << 2 
    Asia = 8,      // 1 << 3 
    Africa = = 16,     // 1 << 4 
    Australia = 32,    // 1 << 5 
    Anarctica = 64     // 1 << 6 
} 

Persons表可能只是簡單地有一個名爲Contintents的int列。爲了表明一個人訪問了歐洲和亞洲:

UPDATE Persons SET Continents = (4 + 8) WHERE Id = whatever 

要查找誰訪問過南極的人,我們使用按位數學:

SELECT * FROM Persons WHERE Continents & 64 = 64 

要查找誰已經訪問了非洲和亞洲的人:

SELECT * FROM Persons WHERE Continents & (16 + 8) = (16 + 8) 

要查找誰訪問過澳大利亞或南美人:

SELECT * FROM Persons WHERE Continents & (32 + 2) != 0 

一個缺點是,雖然整數列在SQL中是可索引的,但它們的位組件不是。一些優化來解決這個問題,對於上述查詢:

SELECT * FROM Persons WHERE Continents & 64 = 64 AND Continents >= 64 

SELECT * FROM Persons WHERE Continents & (16 + 8) = (16 + 8) AND Continents >= (16 + 8) 

SELECT * FROM Persons WHERE Continents & (32 + 2) != 0 AND Continents >= 2 
+1

然後最終你想使用關係數據庫報告工具生成一個很好的報告,但這些數字對報告的最終用戶沒有意義,所以你需要將數字映射到大陸,然後你會想知道有多少人訪問了3個或更多的大陸,你需要引入一個函數或另一個映射,以便報告工具可以選擇。爲什麼要這樣對你自己?如果使用關係數據庫,關係結構最終非常有用。 – Glenn 2012-08-02 18:12:29

+7

-1違反1NF,在便宜的TB級硬盤的時代空間優化,不能擴展到64米以上的區域,採用二進制數學反模式 – Andomar 2012-08-02 18:19:54

1

好吧,我會去反對(目前)民意在這裏簡單地陳述一些事實

  • SQL和關係模型是同樣的事情。
  • 關係模型(理論)的作品有關係的變量,即所謂relvars
  • SQL數據庫使用表。
  • 表和relvars是不一樣的,但也可以是 - 所有的實際目的。
  • 使用關係建模理論,表格應代表relvars。
  • 對於一個表來表示關係變量下面應該是真實的:

    1. 行沒有順序
    2. 列沒有爲了
    3. 沒有重複的行
    4. 每一行和列交叉有列定義類型只有一個值
    5. 沒有特殊的隱藏列(row-id,object id ...)

所以,你可以用表和SQL即出關系設計理論的範圍很多東西,但你失去的「關係」待遇

技術上您的文章(問題)有兩個答案。

  • 是,在文章的標題。
  • 沒有,到後期的身體。
相關問題