sqlite数据库体系结构 - 引用多行

时间:2014-06-14 23:16:13

标签: sql database-design relational-database

我有一个表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中引用所有这些表?这是我目前唯一模糊的想法,但这似乎不太正确......有没有一种好方法可以做到这一点?

3 个答案:

答案 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,但纯粹从数据库的角度来看,你的模型应该是这样的:

enter image description here

  • 每个构造在构造表中都有一行。
  • 每个材料在MATERIAL表中排成一行。
  • BOM 1 中的每一行都是CONSTRUCTION_MATERIAL表中的一行,通过composite键{CONSTRUCTION_ID,LAYER}标识。

换句话说,这是构造和材料之间的多对多关系,而CONSTRUCTION_MATERIAL表充当“结点”或“链接”表 2 。如有必要,您可以将“数量”等字段添加到联结表中。


1 条例草案或材料。

2 虽然略有“异常”:MATERIAL_ID不是允许相同结构的不同层中的相同材料的键的一部分。相反,如果每个构造只能出现一次相同的材质,则只需制作另一个复合键:{CONSTRUCTION_ID,MATERIAL_ID}。