我有一个表materials
,其中包含(我正在使用web2py):
materials_db.define_table('materials',
Field('name','string'),
Field('reference','string'),
Field('manufacturer','string'),
Field('date_added','date'),
Field('density','double'), # Density - kg/m³
Field('emissivity','double'),
Field('specific_heat','double'), # Specific Heat - kJ/kg.K
Field('thermal_conductivity','double') # Thermal conductivity - W/m.K
)
我现在想创建一个表constructions
。每个结构是有序方式的任何数量的材料的组件,例如,像这样的东西:
+------------+-------+
| Material | Layer |
+------------+-------+
| Concrete | 1 |
| Airgap | 2 |
| Insulation | 3 |
| Plaster | 4 |
+------------+-------+
Layer
应该可以更改构造中材质的位置。构造将具有新属性,这些属性将根据所用材料的属性和构造中的位置进行计算。
我真的不知道如何去做。构造中layer
的值必须是唯一的,但显然在构造之间不能是唯一的,即每个构造都可以有一个值为1的图层。
我是否需要为每个构造创建一个新表,然后在表constructions
中引用所有这些表?这是我目前唯一模糊的想法,但这似乎不太正确......有没有一种好方法可以做到这一点?
答案 0 :(得分:1)
你有两个名词:材料和结构。任何材料项目可以进入多个结构,任何结构可以由多种材料组成。这是一种经典的多对多关系。名词成为保存在表格中的实体。交叉表定义了关系:
create table MatConst(
MatID int not null, -- Foreign key to Material table
ConstID int not null, -- Foreign key to Construction table
Qty number not null, -- The number, volume or weight of Mat in Const.
primary key( MatID, ConstID )
);
两个外键成为关系表的主键,因此对于每个正在构建的东西,只能有一个混凝土入口,一个用于石膏等等。数量字段允许数量为57(混凝土磅)或150(平方英尺石膏)。当然,您可以根据需要添加描述关系的其他列。
答案 1 :(得分:1)
写下描述应用程序情况所需的语句。
每个语句都有一个表格。表包含使其语句成立的行。
materials(material_id,name,...) // material [material_id] has name [name] and ...
constructions(construction_id,purpose,...) // construction [construction_id] is good for [purpose] and ...
construction_layers(construction_id,material_id,layer) // construction [construction_id] layer [layer] is [material_id]
将数据库限制在可能出现的状态。
只会出现一些应用情况。语句加上这些情况意味着只能出现一些数据库状态。告诉DMBS它可以阻止其他状态。在约束中说出来。
Keys(PKs和UNIQUE列集)表示基表的值受到约束。 FK表示两个表相互制约。
materials(material_id,name,...) // material [material_id] has name [name] and ...
pk (material_id)
constructions(construction_id,purpose,...) // construction [construction_id] is good for [purpose] and ...
pk (construction_id)
construction_layers(construction_id,material_id,layer) // construction [construction] layer [layer] is [material_id]
pk (construction_id,layer)
fk (construction_id) references constructions (construction_id)
fk (material_id) references materials (material_id)
如果DBMS适用于每个construction_layers行
,那就太好了CHECK(layer >= 1)
但如果没有特定DBMS的触发器,那可能会或可能不会。
我们还想检查每个构造的层是否连续(可能不是所有时间)。您必须通过当前DBMS下的触发器来完成。
以某种方式限制您在声明中所说的内容。
除了键列之外,基表中应该具有的唯一属性是整个键的函数。 (这在5NF中给出了一个表。)(任何时候计算列都可以。)
未从给定基表派生的其他信息应位于单独的基表中。
您想要的任何其他表都应该作为查询或视图。
答案 2 :(得分:1)
我不熟悉web2py,但纯粹从数据库的角度来看,你的模型应该是这样的:
换句话说,这是构造和材料之间的多对多关系,而CONSTRUCTION_MATERIAL表充当“结点”或“链接”表 2 。如有必要,您可以将“数量”等字段添加到联结表中。
1 条例草案或材料。
2 虽然略有“异常”:MATERIAL_ID不是允许相同结构的不同层中的相同材料的键的一部分。相反,如果每个构造只能出现一次相同的材质,则只需制作另一个复合键:{CONSTRUCTION_ID,MATERIAL_ID}。