4

我有一个名为 的表assets,其中资产可以属于用户、团队或部门,并且可能属于每个部门的多个。我的问题是资产是高度可变的,并且可以具有与它们相关联的属性,这些属性对于每个资产都是不同的。

前任。这些可能是资产:

1.)
type:workbench
cost:200
vendor:Acme Co.
color:black
2.)
type:microscope
serial_no:BH-00102
purchase_date:1337800923
cost:2040

这可能会持续到数百到数千种不同类型的资产。

如何以易于查询的规范化方式存储此类数据,而无需在每次添加新资产类型时更改我的表?一些字段也存在于所有资产中,例如成本。

到目前为止,我认为我应该拥有:

assets
id,cost,purchase_date,asset_type_id

asset_types
id,name

division_assets
division_id,asset_id

user_assets
user_id,asset_id

但我不知道将不同的数据放在哪里

4

5 回答 5

3

我建议这样做:

assets (

   id
   asset_type_id
   vendor_id
   cost
   purchase_date

)

asset_poperties (

    id
    asset_id
    asset_property_type_id
    value

)

asset_property_types (

     id
     property_type

)

asset_types (

   id
   asset_type

)

vendors (

   id
   vendor

)
于 2013-02-17T07:43:56.927 回答
3

当我过去遇到这个问题时,“最佳”答案总是会根据我想在数据库中进行多少处理,以及在客户端代码中处理多少而有所不同。

对于它的价值,过去对我来说最有效的方法通常是每个可选属性都有一个表(特别是每个实体类型不是一个表)。所以,在你上面的例子中

assets (as per your example)
asset_types (as per you example)
division_assets (as per your example)
user_assets (as per your example)
colours
  asset_id, colour
weights
  asset_id, weight
serial_numbers
  asset_id, serial_number

当然,根据您需要做出的权衡,这对您来说可能是一个糟糕的选择。就个人而言,我喜欢尽可能明确地保持数据架构,包括数据类型和约束,因此下次出现新属性时更改表没有什么戏剧性的事情。

于 2013-02-17T08:49:57.107 回答
2

您可以为asset_metadata 添加另一个表

asset_metadata
asset_metadata_id,asset_id,metadata_name,metadata_value

如果要对元数据进行规范化和分类,请将其规范化为:

asset_metadata
asset_metadata_id,asset_id,metadata_name_id,metadata_value

metadata_name
metadata_name_id,metadata_name_text
于 2013-02-17T07:50:54.560 回答
2

我建议将成本等常见属性放在常规列中。然后再添加一列,在其中放置所有其他可变资产属性的序列化集合。

CREATE TABLE assets (
  asset_id INT AUTO_INCREMENT PRIMARY KEY,
  cost NUMERIC(9,2),
  purchase_date DATE,
  variables TEXT
);

您可以将集合序列化为 JSON 或 XML 或任何您想要的。使用您的应用程序代码最容易处理的任何内容。

INSERT INTO assets VALUES (123, 49.95, CURDATE(), 'color: black; vendor: Acme Co.');

优点是您可以随时向文本 blob 添加新属性。缺点是您不能读取或写入单个属性,您必须将整个集合视为一个块。

但是您可以索引单个属性以使其可搜索。您需要为要搜索的每个属性创建一个新表(但这可能是所有属性的一小部分):

CREATE TABLE asset_color (
  asset_id INT NOT NULL,
  color VARCHAR(10),
  PRIMARY KEY (asset_id, color),
  KEY(color)
);

并非所有资产都记录在此表中,只有那些具有颜色的资产。

然后,您可以对所有具有颜色属性的资产进行索引搜索:

SELECT assets.*
FROM assets INNER JOIN asset_color USING (asset_id);

您还可以对具有颜色属性且颜色为黑色的资产进行索引搜索:

SELECT assets.*
FROM assets INNER JOIN asset_color USING (asset_id)
WHERE color = 'black';

实际上没有办法设计一个允许变量属性的规范化数据库。所有范式首先要求表是一个关系。根据定义,关系必须具有一组固定的属性。

其他人推荐 EAV 表,但 EAV 中的“值”列不符合具有类型的关系列的定义(其他后果是约束在 EAV 表中不起作用)。因此,EAV 表不是关系,也不能满足任何范式。

于 2013-02-17T08:28:06.103 回答
-1

您可以创建两个新表:

1) 在下表中定义多个资产属性(与资产一样多)

资产ID

资产属性

资产值

2)asset_attribute 表

属性ID

资产属性

逻辑是需要首先在asset_attribute 表中定义asset_attributes,然后它可以与任何资产(作为外键,从UI 上的下拉列表中)一起使用(链接/标记)并输入适当的值。

希望这可以帮助。

于 2013-04-20T05:16:12.957 回答