php - 关系数据库设计 - 规范化和关系

标签 php mysql database relationships database-normalization

我是设计数据库的新手,我不确定我是否在为我的应用程序设计数据库时正确实现了规范化和关系。

正在设计的应用程序可处理购物 list 和产品,并将按如下方式使用数据库:

  • 用户通过 facebook 登录网站。
  • 有一个包含数百万个“产品代码”的大表。每个产品代码代表不同的产品(例如 Apple、电视、手机、牙刷等)。
  • 用户可以创建各种购物 list ,每个购物 list 将包含一个或多个“产品代码”。

我已经“尝试”为数据库创建两种不同的设计,试图推断出哪一种可能更适合该场景。一个使用一对多关系,一个使用多对多关系,两者都将 shopping_list 链接到 product:

enter image description here

问题:

  1. 关于一对多:考虑到会有数百万个不同的产品 ID,一对多设计不会产生一个assigned_products 表中有很多冗余信息?产品表的字段类似于:

     ________________________________________________
    |assigned_p_id | shopping_list_id | product_code |
    |--------------+------------------+--------------|
    |      1       |        1         |   aa11aab    |
    |--------------+------------------+--------------|
    |      2       |        1         |   zz1bbbb    |
    |--------------+------------------+--------------|
    |      3       |        2         |   aa11aab    |
    

如您所见,aa11aab 被重复了两次,因为其他人创建了一个包含相同项目的购物 list ,因此我想知道这种冗余是否会导致数据库问题,每次重复 product_code 都会产生不必要的空间量会采取?

  1. 关于多对多:该图似乎通过让表shopping_list_products 存储 id 值而不是重复 product_code 来消除冗余,但是,这会不会在检索信息时造成性能损失?我假设必须在表格之间进行一些联接,以便每个用户都能获得他们的所有购物 list 以及该购物 list 中的产品代码。

  2. 一般来说:我的关系/规范化可能有任何错误吗? (我是这方面的新手)

最佳答案

这里有一些关于从哪里开始的建议。

您需要一个表来存储有关购买的信息。在数据中可以看到 Wile E Coyote 购买了 Dyno-might 和钢琴...

CREATE TABLE IF NOT EXISTS `purchase` (
    `id`           int unsigned      NOT NULL AUTO_INCREMENT,
    `user_id`      int unsigned      NOT NULL,
    `item_id`      int unsigned      NOT NULL,
    `quantity`     double            DEFAULT 1,
    `price`        double            NOT NULL,
    `qwhen`        datetime          NOT NULL,
    PRIMARY KEY (`id`),
    FOREIGN KEY (`user_id`) REFERENCES user(id) ON DELETE RESTRICT ON UPDATE CASCADE,
    FOREIGN KEY (`product_id`) REFERENCES product(id) ON DELETE RESTRICT ON UPDATE CASCADE
) ENGINE=InnoDB Comment='Purchases';

purchase data
+----+---------+------------+----------+--------+---------------------+
| id | user_id | product_id | quantity |  price | created             |
+----+---------+------------+----------+--------+---------------------+
|  1 |       1 |          1 |        1 | 100.00 | 2016-07-02 20:42:13 |
|  1 |       1 |          3 |        1 | 734.23 | 2016-07-02 21:23:40 |
| .. | ....... | .......... | ........ | ...... | ................... |
+----+---------+------------+----------+--------+---------------------+

您还需要一个表来存储有关产品的信息。我假设您销售的是实体产品,因此我添加了 eanupca 和其他一些可能有用的列。

CREATE TABLE IF NOT EXISTS `product` (
    `id`                 int unsigned      NOT NULL AUTO_INCREMENT,
    `manufacturer_id`    int unsigned      NOT NULL,
    `ean`                int unsigned      NOT NULL,
    `upca`               int unsigned      NOT NULL,
    `upce`               int unsigned      NOT NULL,
    `name`               varchar(100)      NOT NULL,
    `height`             double            DEFAULT NULL,
    `width`              double            DEFAULT NULL,
    `depth`              double            DEFAULT NULL,
    `weight`             double            DEFAULT NULL,
    PRIMARY KEY (`id`),
    FOREIGN KEY (`manufacturer_id`) REFERENCES manufacturer(id) ON DELETE RESTRICT ON UPDATE CASCADE
) ENGINE=InnoDB Comment='Item master file';

product data
+----+-----------------+---------------+--------------+--------+------------+--------+-------+-------+--------+
| id | manufacturer_id | ean           | upca         | upce   | name       | height | width | depth | weight |
+----+-----------------+---------------+--------------+--------+------------+--------+-------+-------+--------+
|  1 |               1 | 1234567890123 | 123456789012 | 123456 | Dyno-might |   12.0 |   1.0 |   1.0 |    0.5 |
|  2 |               1 | 2345678901234 | 234567890123 | 234567 | UltraLaser |   96.0 |  96.0 |  96.0 |  450.0 |
|  3 |               2 | 3456789012345 | 345678901234 | 345678 | Piano      |   36.0 |  60.0 |  72.0 |  375.0 |
| .. | ............... | ............. | ............ | ...... | .......... | ...... | ..... | ..... | ...... |
+----+-----------------+---------------+--------------+--------+------------+--------+-------+-------+--------+

当我们向人们推销东西时,最好正式地称呼他们,所以我们应该有一个有效的称呼表。 user 表将有一个指向该表的外键。

CREATE TABLE IF NOT EXISTS `salutation` (
    `id`           varchar(5)     NOT NULL,
    PRIMARY KEY (`id`)
) ENGINE=InnoDB Comment='Salutations';

salutation data
+------+
| id   |
+------+
| Mr.  |
| Mrs. |
| Miss |
| Ms.  |
| Dr.  |
| Rev. |
| .... |
+------+

名字后缀是人名的一部分,因此我们将把它作为 user 表的一部分,并为该表提供一个外键。

CREATE TABLE IF NOT EXISTS `suffix` (
   `id`           varchar(5)     NOT NULL,
   PRIMARY KEY (`id`)
) ENGINE=InnoDB Comment='Suffixes';

suffix data
+-----+
| id  |
+-----+
| Sr. |
| Jr. |
| II  |
| III |
| IV  |
| ... |
+-----+

当然,我们有用户 - 尽管称他们为客户可能更合适。

CREATE TABLE IF NOT EXISTS `user` (
    `id`              int unsigned   NOT NULL AUTO_INCREMENT,
    `facebook_id`     int unsigned   NOT NULL,
    `email`           varchar(255)   NOT NULL,
    `salutation_id`   varchar(5)     NOT NULL,
    `first_name`      varchar(50)    NOT NULL,
    `middle_name`     varchar(50)    DEFAULT NULL,
    `last_name`       varchar(50)    NOT NULL,
    `suffix_id`       varchar(5)     DEFAULT NULL,
    PRIMARY KEY (`id`),
    FOREIGN KEY (`salutation_id`) REFERENCES salutation(id) ON DELETE RESTRICT ON UPDATE CASCADE,
    FOREIGN KEY (`suffix_id`) REFERENCES suffix(id) ON DELETE RESTRICT ON UPDATE CASCADE
) ENGINE=InnoDB Comment='Users';

user data
+----+-------------+------------------------+---------------+------------+-------------+-----------+-----------+
| id | facebook_id | email                  | salutation_id | first_name | middle_name | last_name | suffix_id |
+----+-------------+------------------------+---------------+------------+-------------+-----------+-----------+
|  1 |   123456789 | coyote_guy32@gmail.com | Mr.           | Wile       | E           | Coyote    | NULL      |
| .. | ........... | ...................... | ............. | .......... | ........... | ......... | ......... |
+----+-------------+------------------------+---------------+------------+-------------+-----------+-----------+

关于php - 关系数据库设计 - 规范化和关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38165740/

相关文章:

php - 如何使用 Codeigniter 将数组插入 MySQL?

mysql - sql如何设置新列的默认值 bool 值?

python - 使用python将整个文本文件加载到数据库中

database - 清理网络用户的 R 查询

javascript - 根据div的内容左右滑动div?

php - 学说 2 @Version 不起作用

php - 当条件满足时跳出 if 语句和循环

php - 我需要将 mysql 查询转换为 CakePHP 条件

mysql - 我想导出没有 "b"的 csv 文件

php - 我的代码中哪种语法是正确的?