2011-11-29 85 views
8

這個表是否對mysql有好處?我希望將來可以靈活地使用這種類型的數據存儲。有了這個表的結構,你不能用一個PRIMARY KEY,但指數...mysql表結構建議?

我應該改變表的格式有頭 - 主鍵,寬度,長度,空間耦合...

ID_NUM Param Value 
1 Width 5e-081 
1 Length 12 
1 Space 5e-084 
1 Coupling 1.511 
1 Metal Layer  M3-0 
2 Width 5e-082 
2 Length 1.38e-061 
2 Space 5e-081 
2 Coupling 1.5 
2 Metal Layer  M310 
+1

SHEF,它的工作,但不能進行標準化。 – nageeb

+0

我認爲主鍵必須是唯一的? – Gordon

+1

這不能歸一化,因爲它不是一個關係。 –

回答

10

不,這是關係數據庫的糟糕設計。這是Entity-Attribute-Value設計的一個例子。它很靈活,但它打破了關於數據庫關係的大部分規則。

在作爲靈活數據庫的解決方案進入EAV設計之前,請閱讀以下故事:Bad CaRMa

更具體地說,一些與EAV的問題包括:

  • 你不知道什麼屬性存在任何給定的ID_NUM不詢問他們。
  • 你不能強制任何屬性,相當於NOT NULL。
  • 您不能使用數據庫約束。
  • 您不能使用SQL數據類型; value列必須是長VARCHAR。
  • 特別是在MySQL中,每個VARCHAR都存儲在它自己的數據頁面上,所以這非常浪費。

當您使用EAV設計時,查詢也非常複雜。開源電子商務平臺Magento廣泛使用EAV,許多用戶表示,如果需要自定義報告,查詢速度非常慢並且很難查詢。

要成爲關係型數據庫,您應該將每個不同的屬性存儲在自己的列中,並使用自己的名稱和適當的數據類型。

我在我的演示文稿Practical Object-Oriented Models in SQL和我的博客文章EAV FAIL以及我的書SQL Antipatterns: Avoiding the Pitfalls of Database Programming中已經寫了更多有關EAV的內容。

+0

+1問題的優秀彙總 – Elemental

0

創建特別爲將來使用的表格時,您必須要提出的主要問題是如何檢索此數據以及它具有什麼用途。就我個人而言,我總是擁有一個唯一的標識符,通常是表格的ID。

看着你的列表似乎沒有任何東西可以唯一地定義條目,所以你將無法跟蹤重複的條目,也不能唯一地檢索記錄。

如果您想保留此設計,您可以創建一個由名稱和參數值組成的組合主鍵。

CREATE TABLE testtest (
    ID INT NOT NULL PRIMARY KEY AUTO_INCREMENT, 
    Name VARCHAR(100) NOT NULL, 
    value number NOT NULL 
/*add other fields here*/ 
); 

CREATE TABLE testtest (
    name VARCHAR(100) NOT NULL, 
    value int NOT NULL, 
/*add other fields here*/ 
    primary key(name,value) 
); 

那些創建表的例子表達了上述2個選項。

1

以我的經驗來說,這種按行存儲字段的想法需要非常小心 - 雖然它看起來有很多優點,但它使得許多常見任務變得更加困難。

積極的一面:它可以在不改變數據庫結構的情況下輕鬆擴展,並以某種方式抽象出數據存儲的細節。在消極的一面:你需要看看存儲字段的所有日常事物在數據庫管理系統中,列式自動地給你提供:簡單的內部/外部連接,一個語句插入/更新,唯一性,外鍵和其他數據庫級別約束檢查,簡單過濾搜索結果的排序。

考慮在您的體系結構中查詢返回MetalLayer = X和寬度在y和z之間的所有項 - 結果按Coupling的長度排序。這個查詢對於構造來說要困難得多,對於DBMS來說,執行要比使用列來存儲特定字段要困難得多。

在餘額中,我唯一使用類似於你所建議的結構的結構是在需要隨機添加隨機非結構化附加數據的情況下。在我看來,如果沒有辦法做出更傳統的餐桌結構工作,這將是最後的策略。

1

你認爲什麼叫EAV model (Entity–Attribute–Value)

它有幾個缺點,就像在執行引用完整性約束嚴重的困難。另外,您必須提出的查詢將比使用規範化表格作爲第二個建議(帶有列的表格:Primary Key, Width, Length, Space, Coupling, etc)要複雜一些。

因此,對於一個簡單的項目,不要使用EAV模型。

如果您的計劃是針對更復雜的項目,並且您希望獲得最大的靈活性,請不要使用EAV。你應該看看6NF (6th Normal Form)這更難以實現,當然在MySQL中不是一件容易的事情。但是,如果成功,您將擁有兩項商品:靈活性和最高級別的歸一化(有些人稱爲「EAV」爲「6NF錯誤地執行了」)。

1

需要考慮的幾件事:

沒有單個主鍵。這可以通過使主鍵由兩列組成(例如在Carl T的第二個例子中)來克服。

參數列被重複並且規範化這個,你應該看看MGA的例子。

第三,「金屬層」列是一個字符串,而不是像其他值一樣的浮點值。

所以最好去像這樣的表DEF:

create table yourTable(
    ID int primary key, 
    ParamId int not null, 
    Width float, 
    Length float, 
    Space float, 
    Coupling float, 
    Metal_layer varchar(20), 
    Foreign key(ParamID) references Param(ID), 
    Value varchar(20) 
) 
create table Param(
    ID int primary key, 
    Name varchar(20) 
)