2011-11-29 93 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) 
)