【问题标题】:SQL table normalization: Simple question about restricting record participation in a many to many relationSQL 表规范化:关于限制记录参与多对多关系的简单问题
【发布时间】:2010-10-21 02:18:51
【问题描述】:

如果你有以下表和关系:

  • 产品表
  • 价格点表(产品的一个或多个价格)
  • 版本表(同一区域销售的产品组)

以及任何给定版本中只能存在一个产品价格的约束。 您将如何构建表格以反映约束条件?

为了说明限制,我有一个价格为 1 美元、2 美元和 3 美元的产品。 我有 A、B、C、D、E、F、G、H、I 的媒体区(每个都代表像俄亥俄州哥伦布这样的地方)

product A price $1 goes to A, B, C
product A price $2 goes to D, E, F
product A price $3 goes to G, H, I

产品 A 在 A、B、C 中存在时价格为 1 美元,在 A、B、C 中不能有其他价格(2 美元、3 美元)

将版本 M2M 表添加到 PricePoints,然后在 M2M 表上的所有字段减去 PricePoint 字段的唯一索引是否有效? (打字时想了想)有没有更好的方法来表示这种关系?

【问题讨论】:

    标签: sql foreign-key-relationship unique-constraint


    【解决方案1】:

    我在理解您的问题时遇到了一些问题。我不明白“产品 A 存在于 A、B、C 中时价格为 1 美元,而不能存在于 D、E、F、G、H、I 中”的说法。为了这个答案,我假设“版本”和“媒体区”是同一回事。

    使用包含三个字段的中间定价表:product_id、version_id 和 price_id。此表的主键(如果您选择使用增量非智能键,则为唯一索引)是 (product_id, version_id)。

    【讨论】:

    • 关于错误的好消息。我重写了它,以便更好地反映真实情况。
    • 好的,所以我认为我提供的解决方案应该可以为您解决(很可能与您在最后一段中建议的解决方案相同)。
    【解决方案2】:

    以下是我将如何根据提供的数据构建表以反映约束:

    SQL DDL:

    CREATE TABLE Products
    (
     product_name CHAR(1) NOT NULL UNIQUE
    );
    
    CREATE TABLE ProductPrices
    (
     product_name CHAR(1) NOT NULL
        REFERENCES Products (product_name), 
     product_price DECIMAL(19, 4) NOT NULL
        CHECK (product_price > 0), 
     UNIQUE (product_name,  product_price)
    );
    
    CREATE TABLE MediaZones
    (
     zone_name CHAR(1) NOT NULL UNIQUE
    );
    
    CREATE TABLE Versions
    (
     product_name CHAR(1) NOT NULL, 
     product_price DECIMAL(19, 4) NOT NULL, 
     FOREIGN KEY (product_name,  product_price)
        REFERENCES ProductPrices (product_name,  product_price), 
     zone_name CHAR(1) NOT NULL 
        REFERENCES MediaZones (zone_name), 
     UNIQUE (product_name, zone_name)
    );
    

    SQL DML(成功 = 好):

    INSERT INTO Products (product_name) VALUES ('A');
    
    INSERT INTO MediaZones (zone_name) 
       VALUES ('A'), ('B'), ('C'), 
              ('D'), ('E'), ('F'), 
              ('G'), ('H'), ('I');
    
    
    INSERT INTO ProductPrices (product_name, product_price) 
       VALUES ('A', 1),
              ('A', 2), 
              ('A', 3);
    

    SQL DML(失败 = 良好):

    INSERT INTO Versions (product_name, product_price, zone_name) 
       VALUES ('A', 1, 'G');
    
    INSERT INTO Versions (product_name, product_price, zone_name) 
       VALUES ('A', 1, 'A');
    
    INSERT INTO Versions (product_name, product_price, zone_name) 
       VALUES ('A', 1, 'Z');
     INTO Versions (product_name, product_price, zone_name) 
       VALUES ('A', 2, 'A');
    
    etc etc 
    

    【讨论】:

      【解决方案3】:

      除非您可以明确地说产品-价格组合仅允许在特定区域中使用,否则我认为最好放弃数据约束并在存储过程或其他业务层使用业务规则约束来检查以查看哪些数据在尝试将产品价格区域组合添加到数据库之前存在。

      【讨论】:

        猜你喜欢
        • 2013-04-19
        • 2023-03-03
        • 1970-01-01
        • 2011-01-05
        • 1970-01-01
        • 1970-01-01
        • 2015-09-11
        • 2014-10-03
        • 2017-09-18
        相关资源
        最近更新 更多