这个表对mysql有什么好处吗?我希望将来能够灵活地使用这种类型的数据存储。使用此表结构,您不能使用PRIMARY KEY而是使用索引...
我应该更改表格的格式以包含标题 - 主键,宽度,长度,空格,耦合......
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
答案 0 :(得分:11)
不,这对于关系数据库来说是一个糟糕的设计。这是Entity-Attribute-Value设计的一个例子。它很灵活,但它打破了关键数据库的大部分规则。
在您作为灵活数据库的解决方案进入EAV设计之前,请阅读以下故事:Bad CaRMa。
更具体地说,EAV的一些问题包括:
value
列必须是长VARCHAR。使用EAV设计时,查询也非常复杂。 Magento是一个开源电子商务平台,广泛使用EAV,许多用户表示,如果您需要自定义报告,则查询速度非常慢且难以查询。
要成为关系型,您应该将每个不同的属性存储在自己的列中,并使用自己的名称和相应的数据类型。
我在演示文稿Practical Object-Oriented Models in SQL和我的博文EAV FAIL以及我的书SQL Antipatterns: Avoiding the Pitfalls of Database Programming中写了更多关于EAV的文章。
答案 1 :(得分:2)
您的建议称为 EAV model (Entity–Attribute–Value)
它有一些缺点,例如强制执行参照完整性约束的严重困难。此外,您必须提出的查询将比使用规范化表格作为您的第二个建议(带有列的表格Primary Key, Width, Length, Space, Coupling, etc
)更复杂。
因此,对于一个简单的项目,不要使用EAV模型。
如果您的计划是针对更复杂的项目而您希望获得最大的灵活性,请不要使用EAV。您应该查看 6NF (6th Normal Form)
,这更难实现,当然也不是MySQL中的一项简单任务。但如果你成功了,你将拥有两种产品:灵活性和最高级别的标准化(有些人将“ EAV ”称为“ 6NF做错了”)。
答案 2 :(得分:1)
根据我的经验,这种逐行存储字段的想法需要非常仔细地考虑 - 虽然它似乎有许多优点,但它使许多常见任务变得更加困难。
从积极的方面来说:它可以在不改变数据库结构的情况下轻松扩展,并在某些方面抽象出数据存储的细节。
在消极方面:您需要查看所有日常事物存储字段按列在DBMS中自动为您提供:简单的内部/外部联接,一个语句插入/更新,唯一性,外键和其他数据库级别约束检查,简单过滤搜索结果的广告排序。
在您的体系结构中考虑一个查询,返回所有项目,其中MetalLayer = X,y和z之间的宽度 - 结果按长度耦合排序。这个查询对于你来说构建起来要困难得多,而DBMS执行起来要比使用列来存储特定字段要困难得多。
在余额中,我唯一一次使用类似于您建议的结构的结构是在需要在临时基础上添加随机非结构化附加数据的上下文中。在我看来,如果我无法使更传统的桌面结构工作,这将是最后的策略。
答案 3 :(得分:1)
这里要考虑的一些事情:
没有单个主键。这可以通过使主键由两列(如Carl T的第二个示例中)
组成来克服重复Param列并规范化,你应该看一下MGA的例子。
第三,"金属层" column是一个字符串,而不是其他的float值。
所以最好选择像这样的表格:
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)
)
答案 4 :(得分: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)
);
这些create table示例表达了上述两个选项。