【问题标题】:database primary key based on variable number of customer subdivisions基于可变数量的客户细分的数据库主键
【发布时间】:2013-10-28 18:43:46
【问题描述】:

在 Groovy/Grails 和 GORM 中使用 MySQL 数据库执行此操作。

在为我们的不同客户存储数据时,我们需要能够识别他们的细分。有些将有 0 个细分级别。一些,1、2、3、级别等。我们希望允许任意数量的细分级别,但可以设置为固定数字,例如 5、7 或 10。

例如:

公司 ABC 有 2 个细分级别:

公司)ABC(根级别) 细分级别 1) ABC->Div1, ABC->Div2, ABC->Div3 细分级别 2) ABC->Div1->SubDiv1, ABC->Div1->SubDiv2, ABC->Div1->SubDiv3

公司 DEF 有 1 个级别:

公司)DEF(根级别) 1级)DEF->Div1,DEF->Div2,DEF->Div3

我们需要为每个级别定义 1 到 1 和 1 到多个唯一属性(例如将地址与 ABC->Div1->SubDiv3 关联)

ABC 公司可能希望我们为 Div2 的所有实例和 Div2 的所有细分显示特定图像。

问题是,如何最好地为标识符或主键创建可变数量的划分级别,然后用作相关数据的外键?

有固定数量的列(比如 7 和一个复杂的键):

ID-Level-1、ID-Level-2、ID-Level-3、ID-Level-4、ID-Level-5、ID-Level-6、ID-Level-7

或者,创建某种层次结构树并将各种键值用作标识符/外键?

【问题讨论】:

  • 给定一个节点,是否只有一条到根的路径?换句话说,这是tree 还是DAG
  • @Branko:这是一棵树(不是 DAG)。

标签: mysql sql grails database-design grails-orm


【解决方案1】:

你可以像下面这样建模

class Company {
    static hasMany = [subdivisions: Subdivision]
}

class Subdivision {
    static belongsTo = [company: Company, subdivision: Subdivision]
    static hasMany = [subdivisions: Subdivision]
}

【讨论】:

  • 这种方法看起来更像“Grails”。
【解决方案2】:

像你描述的那样存储它:Company->Div->Subdiv:

id  subdivision_name   subdivision_level    subdivision_path
-----------------------------------------------------------------
 1  ABC                0                    ABC
 2  Div1               1                    ABC->Div1
 3  Div2               1                    ABC->Div2
 4  Div3               1                    ABC->Div3
 5  SubDiv1            2                    ABC->Div1->SubDiv1
 6  SubDiv2            2                    ABC->Div1->SubDiv2
 7  SubDiv3            2                    ABC->Div1->SubDiv3
 8  DEF                0                    DEF
 9  Div1               1                    DEF->Div1
10  Div2               1                    DEF->Div2
11  Div3               1                    DEF->Div3

级别数仅受 subdivision_path 长度的限制 - 标准数据类型应该绰绰有余。

所以让我们将地址与 ABC->Div1->SubDiv3 相关联:

CREATE TABLE addresses (id ... , subdivision_id INTEGER, ...);
ALTER TABLE addresses ADD CONSTRAINT fk_addresses_subdivisions FOREIGN KEY (subdivision_id) REFERENCES subdivisions (id);

...查询 Div2 的所有实例以及 Div2 的所有细分。

SELECT * FROM subdivisions WHERE subdivision_path LIKE 'ABC->Div2%';

...对于 Div2 的所有细分:

SELECT * FROM subdivisions WHERE subdivision_path LIKE 'ABC->Div2->%';

...对于所有根公司:

SELECT * FROM subdivisions WHERE level = 0;

...等等。

或者 subdivision_path 可以存储 id,而不是名称(也许它更好)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-13
    • 1970-01-01
    相关资源
    最近更新 更多