代码之家  ›  专栏  ›  技术社区  ›  cope360

每个客户有选择地覆盖主数据的数据库结构

  •  5
  • cope360  · 技术社区  · 15 年前

    模型和制造商的关系是多对一的。每个租户的数据使用客户id分隔。

    数据模型的要求:

    • 客户选择要使用的主实体
    • 客户可以覆盖主模型或制造商的属性
    • 客户可以创建自己的制造商
    • 客户可以为自己或主制造商创建自己的模型
    • 模型中的其他实体将与这些实体相关,因此希望每个实体都有一个主表,可以使用外键。制造商和型号表在示例中填充了该角色。

    在本例中:

    • 客户1按原样使用福特,替代雪佛兰,并增加两个定制制造商
    • 客户1按原样使用雪佛兰和宝马,并增加一家定制制造商
    • 模型是根据脚本中的注释创建的

    下面是一个满足所有需求的带注释的示例实现。

    • 如何改进这一点?

    制造商表格

    /*
     * Master manufacturers shared between all customers
     */
    CREATE TABLE master_manufacturers (
        master_manufacturer_id INTEGER NOT NULL,
        name VARCHAR(100) NOT NULL,
        attribute_1 VARCHAR(50),
        /* ... */
        attribute_n VARCHAR(50),
        PRIMARY KEY (master_manufacturer_id)
    );
    
    INSERT INTO
        master_manufacturers (master_manufacturer_id, name)
    VALUES
        (1, 'Ford'),
        (2, 'Chevrolet'),
        (3, 'BMW');
    
    /*
     * A Customer's manufacturer.  
     *   If master_manufacturer_id IS NULL, then it is a custom manufacturer and manufacturer_custom contains the data
     *   If master_manufacturer_id IS NOT NULL and manufacturer_custom does not exist, then the master is used without modification
     *   If master_manufacturer_id IS NOT NULL and manufacturer_custom exists, then the master is overridden
     */
    CREATE TABLE manufacturers (
        manufacturer_id INTEGER NOT NULL,
        customer_id INTEGER NOT NULL,
        master_manufacturer_id INTEGER,
        PRIMARY KEY (manufacturer_id),
        FOREIGN KEY (master_manufacturer_id) REFERENCES master_manufacturers (master_manufacturer_id),
        UNIQUE (customer_id, master_manufacturer_id)
    );
    
    INSERT INTO
        manufacturers (manufacturer_id, customer_id, master_manufacturer_id)
    VALUES
        (1, 1, 1),
        (2, 1, 2),
        (3, 1, NULL),
        (4, 1, NULL),
        (5, 2, 2),
        (6, 2, 3),    
        (7, 2, NULL);    
    
    CREATE TABLE manufacturer_custom (
        manufacturer_id INTEGER NOT NULL,
        name VARCHAR(100) NOT NULL,
        attribute_1 VARCHAR(50),
        /* ... */
        attribute_n VARCHAR(50),
        PRIMARY KEY (manufacturer_id),
        FOREIGN KEY (manufacturer_id) REFERENCES manufacturers (manufacturer_id)
    );
    
    INSERT INTO
        manufacturer_custom (manufacturer_id, name)
    VALUES
        (2, 'Chevy'),
        (3, 'Cust 1 Custom 1'),
        (4, 'Cust 1 Custom 2'),
        (7, 'Cust 2 Custom 1');
    

    /*
     * Master models shared between all customers
     */
    CREATE TABLE master_models (
        master_model_id INTEGER NOT NULL,
        master_manufacturer_id INTEGER NOT NULL,
        name VARCHAR(100) NOT NULL,
        attribute_1 VARCHAR(50),
        /* ... */
        attribute_n VARCHAR(50),
        PRIMARY KEY (master_model_id),
        FOREIGN KEY (master_manufacturer_id) REFERENCES master_manufacturers (master_manufacturer_id)
    );
    
    INSERT INTO
        master_models (master_model_id, master_manufacturer_id, name)
    VALUES
        (1, 1, 'F-150'),
        (2, 1, 'F-250'),
        (3, 1, 'Falcon'),
        (4, 2, 'Camaro'),
        (5, 2, 'Corvette'),
        (6, 3, 'M3'),
        (7, 3, '135i');
    
    /*
     * A Customer''s model.  
     *   If master_model_id IS NULL, then it is a custom model and model_custom contains the data
     *   If master_model_id IS NOT NULL and model_custom does not exist, then the master is used without modification
     *   If master_model_id IS NOT NULL and model_custom exists, then the master is overridden
     */
    CREATE TABLE models (
        model_id INTEGER NOT NULL,
        master_model_id INTEGER,
        manufacturer_id INTEGER NOT NULL,
        attribute_1 VARCHAR(50),
        /* ... */
        attribute_n VARCHAR(50),
        PRIMARY KEY (model_id),
        FOREIGN KEY (master_model_id) REFERENCES master_models (master_model_id)
    );
    
    INSERT INTO
        models (model_id, master_model_id, manufacturer_id)
    VALUES
        (1, 1, 1),    /* F-150 for customer_1's Ford */
        (2, 2, 1),    /* F-250 for customer_1's Ford */
        (3, 4, 2),    /* Camaro for customer_1's Chevy */
        (4, 4, 5),    /* Camaro for customer_2's Chevrolet */
        (5, 5, 5),    /* Corvette for customer_2's Chevrolet */
        (6, 6, 6),    /* M3 for customer_2's BMW */
        (7, NULL, 1), /* F-350 (custom) for customer_1's Ford */
        (8, NULL, 6), /* M7 (custom) for customer_2's BMW */
        (9, NULL, 7); /* Custom Model (custom) for customer_2's Custom Mfg */
    
    CREATE TABLE model_custom (
        model_id INTEGER NOT NULL,
        name VARCHAR(100) NOT NULL,
        attribute_1 VARCHAR(50),
        /* ... */
        attribute_n VARCHAR(50),
        PRIMARY KEY (model_id),
        FOREIGN KEY (model_id) REFERENCES models (model_id)
    );
    
    INSERT INTO
        model_custom (model_id, name)
    VALUES
        (7, 'F-350'),        /* F-350 for customer_1's Ford */
        (8, 'M7'),           /* M7 for customer_2's BMW */
        (9, 'Custom Model'); /* Custom Model for customer_2's Custom Mfg */
    

    视图以简化这些表的使用

    /*
     * View for a customer''s manufacturers
     */
    CREATE VIEW vw_manufacturers AS
        SELECT
            m.customer_id,
            m.manufacturer_id, 
            COALESCE(cm.name, mm.name) AS name,
            COALESCE(cm.attribute_1, mm.attribute_1) AS attribute_1,
            /* ... */
            COALESCE(cm.attribute_n, mm.attribute_n) AS attribute_n
        FROM
            manufacturers m
        LEFT JOIN
            master_manufacturers mm
        USING
            (master_manufacturer_id)
        LEFT JOIN
            manufacturer_custom cm
        USING
            (manufacturer_id);
    
    /*
     * View for a customer's models
     */
    CREATE VIEW vw_models AS
        SELECT
            mfg.customer_id,
            mfg.manufacturer_id,
            mfg.name AS manufacturers_name,
            m.model_id,
            COALESCE(cm.name, mm.name) AS name,
            COALESCE(cm.attribute_1, mm.attribute_1) AS attribute_1,
            /* ... */
            COALESCE(cm.attribute_n, mm.attribute_n) AS attribute_n
        FROM
            vw_manufacturers mfg,
            models m
        LEFT JOIN
            master_models mm
        USING
            (master_model_id)
        LEFT JOIN
            model_custom cm
        USING
            (model_id)
        WHERE
            mfg.manufacturer_id = m.manufacturer_id;
    

    客户识别号1的制造商

    SELECT manufacturer_id, name FROM vw_manufacturers WHERE customer_id = 1;

     manufacturer_id |      name       
    -----------------+-----------------
               1 | Ford
               2 | Chevy
               3 | Cust 1 Custom 1
               4 | Cust 1 Custom 2
    

    客户识别号2的制造商

    SELECT manufacturer_id, name FROM vw_manufacturers WHERE customer_id = 2;

     manufacturer_id |      name       
    -----------------+-----------------
               5 | Chevrolet
               6 | BMW
               7 | Cust 2 Custom 1
    

    客户识别号1的型号

    SELECT * FROM vw_models WHERE customer_id = 1;

     customer_id | manufacturer_id | manufacturers_name | model_id |  name  
    -------------+-----------------+--------------------+----------+--------
           1 |               1 | Ford               |        1 | F-150
           1 |               1 | Ford               |        2 | F-250
           1 |               2 | Chevy              |        3 | Camaro
           1 |               1 | Ford               |        7 | F-350
    

    客户识别号2的型号

    SELECT * FROM vw_models WHERE customer_id = 2;

     customer_id | manufacturer_id | manufacturers_name | model_id |     name     
    -------------+-----------------+--------------------+----------+--------------
               2 |               5 | Chevrolet          |        4 | Camaro
               2 |               5 | Chevrolet          |        5 | Corvette
               2 |               6 | BMW                |        6 | M3
               2 |               6 | BMW                |        8 | M7
               2 |               7 | Cust 2 Custom 1    |        9 | Custom Model
    
    2 回复  |  直到 15 年前
        1
  •  2
  •   OMG Ponies    15 年前

    您需要以下表格:

    • 制造商代码
    • 制造商类型代码
    • 制造商详细信息
    • 模型类型代码
    • 模型细节

    回复:制造业及;客户

    下一步是为引擎、轮子等定义类型代码表。我将使用名为MODEL-ATTRIBUTES的外部参照表将它们与MODEL-DETAILS关联起来。模型属性表将包含:

    • 型号-DETAILS-ID(主键)
    • 模型-属性-类型-代码(pk)

    这将允许可选的模型属性与适用的模型详细信息记录相关联,而无需不断向模型详细信息表添加属性。

    制造商代码

    • 描述
    • 有效期不为空

    制造商代码|说明|生效日期|失效日期
    福特|福特| 01-01-1900 | 12-31-9999

    CHEV |雪佛兰| 01-01-1900 | 12-31-9999

    制造商类型代码

    • 制造商类型代码(pk)
    • 说明不为空

    制造商类型代码|说明
    主人|主人

    • 制造商详细信息ID(主键)
    • 制造商代码(fk)不为空
    • 客户ID(fk)不为空

    制造商-详细信息-ID |制造商-代码|制造商-类型-代码|客户-ID

    2 |宝马|定制| 1

    模型

    • 型号ID(pk)


    1 | 1 | M3
    降低1 | 2 | M3

        2
  •  -3
  •   DOOR3 James    15 年前

    这取决于该系统的使用情况。

    理论上,这一切都可以在一张表中。。。。