如何布置我的数据库?

时间:2012-09-26 15:22:33

标签: mysql database database-design

我正在创建一个销售枪支和相关物品的在线商店。我一直致力于使数据库(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 ...

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

*的 修改 *

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

• 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)属性,并且还有更多像这个问题的实例。

感谢您一看:)

3 个答案:

答案 0 :(得分: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

答案 1 :(得分:2)

这是一个简单的设计:

<强>产品

  • PRODUCT_ID
  • PRODUCT_NAME

<强> PRODUCT_CATEGORY

  • PRODUCT_ID
  • CATEGORY_ID

<强>分类

  • CATEGORY_ID
  • CATEGORY_NAME

通过这种设计,每个产品可以有多个类别。如果您向category_parent表格添加Category,则可以设置子类别。

更新1

使用'attributes'代替'categories'并为属性添加值:

<强>产品

  • PRODUCT_ID
  • PRODUCT_NAME

<强> Product_Attribute

  • PRODUCT_ID
  • attribute_id
  • ATTRIBUTE_VALUE

<强>属性

  • attribute_id
  • 属性名称

答案 2 :(得分: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该基表与子表(如子类)。这些子表包含更具体的特定对象类型的信息。

就像我说的那样,不确定这是否是最好的方式,或者其他海报的解决方案是否能更好地运作,但这只是突然出现的问题。