簡體   English   中英

關系數據庫設計 - 規范化和關系

[英]relational database design - normalization and relationships

我是設計數據庫的新手,我不確定我是否在為我的應用程序設計數據庫時正確實現了規范化和關系。

正在設計的應用程序與購物清單和產品一起使用,並將使用如下數據庫:

  • 用戶通過Facebook登錄該網站。
  • 有一張包含數百萬“產品代碼”的大桌子。 每個產品代碼代表不同的產品(例如Apple,TV,手機,牙刷等)。
  • 用戶能夠創建各種購物清單,並且每個購物清單將包含一個或多個“產品代碼”。

我已經“嘗試”為數據庫創建兩種不同的設計,試圖推斷哪種設計可能更適合該場景。 一個使用一對多關系,一個多對多關系,兩者都將shopping_list鏈接到產品

在此輸入圖像描述

問題:

  1. 關於一對多:鑒於將有數百萬個不同的產品ID, 一對多設計難道不會在assigned_products表中產生大量冗余信息嗎? products表的字段類似於:

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

正如你所看到的, aa11aab重復了兩次,因為其他人創建了一個具有相同項目的購物清單,因此我想知道這種冗余是否會產生數據庫問題,每個重復的product_code會占用多少不必要的空間?

  1. 關於多對多:圖表似乎通過使表shopping_list_products存儲id值而不是重復product_code來消除冗余,但是,這會在檢索信息時導致性能損失嗎? 我假設表之間必須進行一些連接 ,以便每個用戶獲得所有購物清單和購物清單中的產品代碼。

  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      |
| .. | ........... | ...................... | ............. | .......... | ........... | ......... | ......... |
+----+-------------+------------------------+---------------+------------+-------------+-----------+-----------+

在這兩種情況下,你基本上都在做同樣的事情。 在第一種情況下,您將shopping_list_id映射到product_code ,在第二種情況下,您將其映射到product_id 無論您使用product_code還是product_id它們似乎都是代表product實體的外鍵。 在這兩種情況下,要到達產品行,您必須使用該字段加入products表。

作為一般規則,您應該映射兩個id列(第二個選項),以便在兩種情況下使用整數主鍵完成連接。 這不僅可以提高存儲和索引的效率,還可以使這些連接速度更快。

此外,正如其中一條評論所指出的,您應該將自動增量主鍵添加到shopping_list_products表中。

另外,對於命名約定,您可能需要考慮始終使用id命名主鍵。 例如,不是擁有products.product_id ,而是每個表都有products.id等。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM