【问题标题】:Automating table normalization自动化表规范化
【发布时间】:2011-03-06 04:21:36
【问题描述】:

我有一个具有这种结构的表(简化):

artID: 1
artName: TNT
ArtBrand: ACME
...

我想对其进行规范化,为品牌制作一个单独的表格(它将包含有关每个品牌的额外数据) 所以我想结束这个

文章表:

artID: 1
artName: TNT
brandID: 1
...

品牌表

brandID: 1
brandName: ACME
brandInfo: xyz
....

此表的品牌太多,无法手动执行此操作。 有什么简单的方法可以自动化吗? 我正在使用 MySQL

【问题讨论】:

  • 每篇文章是否有多个品牌?
  • 不,每篇文章只有一个品牌

标签: mysql database database-design automation normalization


【解决方案1】:
  1. 我会使用create table as select ... 语法来创建品牌 生成 id-s 的表
  2. 创建brand_id 列,并使用article 表中现有的brand 列填充从brands 表生成的id-s。
  3. 从文章表中删除品牌列,当然brand_id除外
  4. 创建外键...

【讨论】:

    【解决方案2】:

    生成品牌表应该相当简单:

    CREATE TABLE brands ( 
      id INT PRIMARY KEY AUTO_INCREMENT, 
      brand_name VARCHAR(50), 
      brand_info VARCHAR(200)
    );
    
    INSERT INTO brands VALUES (brand_name)
    SELECT ArtBrand FROM Table
    GROUP BY ArtBrand;
    

    在您的原始表和新品牌表之间创建关系的类似故事,只是插入中的选择语句将如下所示:

    SELECT t.artId, b.id 
    FROM table t JOIN brands b ON (t.ArtBrand = b.brand_name)
    

    【讨论】:

      【解决方案3】:

      正如其他答案所建议的,您可以使用INSERT ... SELECT 语法来执行以下操作:

      INSERT INTO brands (brandName)
      SELECT   artBrand
      FROM     original
      GROUP BY artBrand;
      
      INSERT INTO articles (artName, brandID)
      SELECT   o.artName, b.brandID
      FROM     original o
      JOIN     brands b ON (b.brandName = o.artBrand);
      

      测试用例:

      CREATE TABLE original (artID int, artName varchar(10), artBrand varchar(10));
      CREATE TABLE articles (artID int auto_increment primary key, artName varchar(10), brandID int);
      CREATE TABLE brands (brandID int auto_increment primary key, brandName varchar(10));
      
      INSERT INTO original VALUES (1, 'TNT1', 'ACME1');
      INSERT INTO original VALUES (2, 'TNT2', 'ACME1');
      INSERT INTO original VALUES (3, 'TNT3', 'ACME1');
      INSERT INTO original VALUES (4, 'TNT4', 'ACME2');
      INSERT INTO original VALUES (5, 'TNT5', 'ACME2');
      INSERT INTO original VALUES (6, 'TNT6', 'ACME3');
      INSERT INTO original VALUES (7, 'TNT7', 'ACME3');
      INSERT INTO original VALUES (8, 'TNT8', 'ACME3');
      INSERT INTO original VALUES (9, 'TNT9', 'ACME4');
      

      结果:

      SELECT * FROM brands;
      +---------+-----------+
      | brandID | brandName |
      +---------+-----------+
      |       1 | ACME1     |
      |       2 | ACME2     |
      |       3 | ACME3     |
      |       4 | ACME4     |
      +---------+-----------+
      4 rows in set (0.00 sec)
      
      
      ELECT * FROM articles;
      +-------+---------+---------+
      | artID | artName | brandID |
      +-------+---------+---------+
      |     1 | TNT1    |       1 |
      |     2 | TNT2    |       1 |
      |     3 | TNT3    |       1 |
      |     4 | TNT4    |       2 |
      |     5 | TNT5    |       2 |
      |     6 | TNT6    |       3 |
      |     7 | TNT7    |       3 |
      |     8 | TNT8    |       3 |
      |     9 | TNT9    |       4 |
      +-------+---------+---------+
      9 rows in set (0.00 sec)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-03-07
        • 2011-05-09
        • 2012-05-22
        • 2012-12-31
        • 2021-11-06
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多