使用组合键

时间:2016-09-04 14:22:55

标签: mysql database grails constraints gorm

我在我的一个旧项目中有这个数据库关系 运动设施有不同运动场地预订。主要是足球;五个方面。 其中一些设施具有我称之为复合字段的功能。我们来举个例子。设施' 4' 3 字段用于五人制足球比赛;让我们用数字 1,2,3 来识别它们。它们的定位方式使得管理者可以移除其中一个分隔符,并将其中的两个组合起来为七个一侧或两者组成一个字段,并为十个一侧创建一个字段。因此,字段4将是 1 + 2 ,字段5将是 2 + 3 ,字段6将 1 + 2 + 3 这是我的SQL代码(这是我用PHP和MySQL编写的旧项目)。

    CREATE TABLE IF NOT EXISTS field (
    id              INT(5) UNSIGNED NOT NULL AUTO_INCREMENT,
    facility_id     INT(5) UNSIGNED NOT NULL,
    internal_id     INT(3) UNSIGNED NOT NULL,
    field_size      VARCHAR(20)     NOT NULL,
    field_type      VARCHAR(20)     NOT NULL,
    is_composite    BOOLEAN         NOT NULL DEFAULT FALSE,
    display_name    VARCHAR(20)     NULL,


    PRIMARY KEY (id),
    UNIQUE (facility_id, internal_id),

    CONSTRAINT fk_field_facility_id FOREIGN KEY (facility_id) REFERENCES facility(id)
        ON UPDATE CASCADE ON DELETE CASCADE
)
;

INSERT INTO field (id, facility_id, internal_id, field_size, field_type, is_composite) VALUES
    (4, 4, 1, 'FIVE_ASIDE', 'PLASTIC', false),
    (5, 4, 2, 'FIVE_ASIDE', 'PLASTIC', false),
    (6, 4, 3, 'FIVE_ASIDE', 'PLASTIC', false),
    (7, 4, 4, 'SEVEN_ASIDE', 'PLASTIC', true),
    (8, 4, 5, 'SEVEN_ASIDE', 'PLASTIC', true),
    (9, 4, 6, 'TEN_ASIDE', 'PLASTIC', true)
;

CREATE TABLE IF NOT EXISTS field_component (
    id                      INT(5) UNSIGNED NOT NULL AUTO_INCREMENT,
    facility_id             INT(5) UNSIGNED NOT NULL,
    composite_internal_id   INT(3) UNSIGNED NOT NULL,
    child_internal_id       INT(3) UNSIGNED NOT NULL,


    PRIMARY KEY (id),
    UNIQUE KEY unq_facility_component_child (facility_id, composite_internal_id, child_internal_id),


    CONSTRAINT fk_field_component_field_child FOREIGN KEY (facility_id, child_internal_id) REFERENCES field(facility_id, internal_id)
        ON UPDATE CASCADE ON DELETE CASCADE,
    CONSTRAINT fk_field_component_field_component FOREIGN KEY (facility_id, composite_internal_id) REFERENCES field(facility_id, internal_id)
        ON UPDATE CASCADE ON DELETE CASCADE
)
;

INSERT INTO field_component (id, facility_id, composite_internal_id, child_internal_id) VALUES
    (1, 4, 4, 1),
    (2, 4, 4, 2),

    (3, 4, 5, 2),
    (4, 4, 5, 3),

    (5, 4, 6, 1),
    (6, 4, 6, 2),
    (7, 4, 6, 3)
;

我正在尝试使用GORM在Grails 3中编写这个项目,原因是学习原因(我在新工作中使用这些项目,如果可能的话,我想重新创建项目并将其提供给某些人)。 正如您在此处所见,我在 field_component 中有两个约束,因此字段由字段中的现有字段引用,但也是如此< em> child 字段由字段中的现有字段引用,并且也属于同一工具。因此,有些人无法将字段作为来自不同设施的组件添加。

在Grails中,我决定尝试以编程方式创建域,并让GORM创建数据库(我实际上是在努力解决这个问题,我总是首先从数据库开始,然后让它指导开发,但之后再也没用过ORM)但是我在重建这些限制时遇到了问题。

我的表field_component基本上是一个连接表,所以我使用带有joinTable的hasMany映射,但问题是通过使用id,我不能强制执行第二个约束来确保子进程提交的是同一设施的一部分。

这是我的Grails代码

class Facility {

    String name

    static hasMany = [fields: Field]

    static constraints = {
        name unique: true, blank: false, maxSize: 30
    }
}

class Field {

    int internalId
    FieldType fieldType
    FieldSize fieldSize
    boolean isComposite

    static belongsTo = [facility: Facility]

    static hasMany = [fieldComponents: Field]

    static mapping = {
        fieldComponents joinTable: [name  : "field_component",
                                    key   : "composite_field_id",
                                    column: "child_field_id"]
    }

    static constraints = {
        internalId min: 1, unique: 'facility'
        fieldType blank: false, defaultValue: FieldType.ARTIFICIAL
        fieldSize blank: false, defaultValue: FieldSize.FIVE_A_SIDE
        isComposite defaultValue: false
    }
}

我在考虑使用组件ID键(而不是默认ID)。 然后我会将 facility_id internal_id 作为主键,我想我可以在joinTanble中引用它,如下所示:

static mapping = {
        fieldComponents joinTable: [name  : "field_component",
                                    key   : "facility_id, internal_id",
                                    column: "child_field_id"]
    }

但我实际上不是100%确定这会起作用。 facility_id 是按照约定在数据库中创建的,但我不确定GORM是多么聪明。 即便如此,我仍然不确定如何强制执行属于同一设施的字段的第二个约束。 这可能是我不应该为此付出太多的努力吗?我可以在添加和保存字段时进行一些验证,但在数据库方面它会允许错误的数据。

对此有何想法?

1 个答案:

答案 0 :(得分:0)

如果你不确定用这个插件仔细检查:

https://grails.org/plugin/db-reverse-engineer

这个插件基于数据库模型创建了groovy类