0

我正在创建一个在线商店来销售枪支和相关物品。我一直致力于完善数据库(MySQL),因为它将成为网站的支柱。我的问题是,在保持规范化优先的同时,我无法理解应该如何布局数据库。该站点有许多产品,并且大多数产品具有相同的信息,但许多产品之间存在细微差别。

例如,弹药有四个类别,四个类别中的三个具有相同的信息,最后一个具有差异。我会为三个相同的表格制作一张表格,而为具有不同信息的一张表格制作一张单独的表格吗?或者我会创建表并有一列可以容纳具有该产品差异的数组或 JSON 字符串?

请记住,有许多产品存在相同的问题。我不害怕工作,我只是想确保我走在正确的道路上。

让我给你一个我的类别的简要布局:

• Firearms
    • handguns (unique characteristics)
    • centerfire rifles (unique characteristics)
    • rimfire rifles (same as above)
• Ammunition
    • rifle ammo (unique characteristics)
    • handgun ammo (same as above)
    • rimfire ammo (same as above)
    • shotgun ammo (unique characteristics)
• Shooting Accessories
    • there are many products here with unique characteristics
• Optics
    • there are many products here with unique characteristics
• MANY MORE ...

我很想制作一张名为 products 的表,并将它们全部放在该表中,但由于存在细微差别,我确信这是不可能的。

*编辑*

这是我将拥有的属性差异的示例:

• Rifle Ammunition
  • manufacturer
  • model
  • caliber
  • bullet weight
  • bullet type
  • number of rounds
  • price
  • description
  • sku
  • rating

• Handgun Ammunition
  • SAME AS ABOVE

• Rimfire Ammunition
  • SAME AS ABOVE

• Shotgun Ammunition
  • manufacturer
  • model
  • gauge
  • shell length
  • shot weight
  • shot size
  • velocity
  • price
  • description
  • sku
  • rating

步枪、手枪和 rimfire 将具有相同数量的属性 (10)。Shotgun 将具有 (11) 个属性,并且还有更多类似此问题的实例。

谢谢你看:)

4

3 回答 3

3

我会做这样的事情:

产品表将非常基本,您的主要产品详细信息:

create table products
(
  id int,
  name varchar(50)
);

insert into products values
(1, 'rifle ammunition'),
(2, 'handgun ammo');

我个人会使用类似于以下的模型:

产品表将非常基本,您的主要产品详细信息:

create table product
(
  part_number int, (PK)
  name varchar(10),
  price int
);
insert into product values
(1, 'product1', 50),
(2, 'product2', 95.99);

第二个属性表来存储每个不同的属性。

create table attributes
(
  id int,
  attribute_name varchar(10),
  attribute_value varchar(10)
);

insert into attributes values
(1, 'manufacturer', 'test'),
(2, 'model', 'blah'),
(3, 'bullet weight', '10'),
(4, 'bullet type', 'metal'),
(5, 'price', '50');

最后创建 product_attribute 表作为每个产品及其关联属性之间的 JOIN 表。此表将允许每个产品和属性的多个条目。因此,如果一个产品有 10 个属性,则将有 10 个条目。如果另一个有 2 个属性,则将有两个条目。

create table products_attributes 
(
  product_id int,
  attribute_id int
);

insert into products_attributes values
(1,  1),
(1,  2),
(1,  3),
(1,  4),
(2,  1),
(2,  2),
(2,  3);

这使您可以灵活地拥有许多具有多个属性或类别的产品。然后查询会很简单,只需几个连接(参见SQL Fiddle With Demo):

select *
from products p
left join products_attributes pa
  on p.id = pa.product_id
left join attributes a
  on pa.attribute_id = a.id;

查询的结果将是:

ID | NAME              | PRODUCT_ID | ATTRIBUTE_ID | ATTRIBUTE_NAME | ATTRIBUTE_VALUE
-------------------------------------------------------------------------------
1  | rifle ammunition  | 1          | 1            | manufacturer   | test
1  | rifle ammunition  | 1          | 2            | model          | blah
1  | rifle ammunition  | 1          | 3            | bullet weight  | 10
1  | rifle ammunition  | 1          | 4            | bullet type    | metal
2  | handgun ammo      | 2          | 1            | manufacturer   | test
2  | handgun ammo      | 2          | 2            | model          | blah
2  | handgun ammo      | 2          | 3            | bullet weight  | 10
于 2012-09-26T15:29:50.867 回答
2

这是一个简单的设计:

产品

  • product_id
  • 产品名称

产品分类

  • product_id
  • 类别ID

类别

  • 类别ID
  • 分类名称

通过这种设计,每个产品都可以有多个类别。如果将 a 添加category_parentCategory表中,则可以有子类别。

更新 1

使用“属性”代替“类别”并向属性添加值:

产品

  • product_id
  • 产品名称

产品_属性

  • product_id
  • 属性ID
  • 属性值

属性

  • 属性ID
  • 属性名
于 2012-09-26T15:29:25.327 回答
0

有很多方法可以做到这一点。也许其他答案是最好的,但我脑海中闪现的第一件事就是做这样的事情:

CREATE TABLE ammunition (
    id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
    -- any columns that are common across ALL categories of ammo,
    PRIMARY KEY (id)
);

CREATE TABLE rifleHandgunRimfireAmmo (
    id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
    -- any columns that are exclusive to rifle/handgun/rimfire ammo,
    fkAmmoID INTEGER UNSIGNED NOT NULL,
    PRIMARY KEY (id),
    FOREIGN KEY (fkAmmoID) REFERENCES ammunition (id)
);

CREATE TABLE shotgunAmmo (
    id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
    -- any columns that are exclusive to shotgun ammo,
    fkAmmoID INTEGER UNSIGNED NOT NULL,
    PRIMARY KEY (id),
    FOREIGN KEY (fkAmmoID) REFERENCES ammunition (id)
);

它基本上就像 OOP。ammunition您有一个包含所有常见信息的基表(有点像基类) 。然后extend是带有子表(如子类)的基表。这些子表包含更特定于该特定对象类型的信息。

就像我说的,不确定这是否是最好的方法,或者其他海报的解决方案是否会更好,但这正是我脑海中浮现的想法。

于 2012-09-26T15:41:52.900 回答