2016-09-04 2 views
1

У меня есть отношение к базе данных в старом проекте шахты , где у атлетического объекта есть поля для разных видов спорта. В основном футбол; пять - сторона. Некоторые из этих объектов имеют то, что я называю составными полями. Давайте возьмем пример. Объект '4' имеет поля для пятистороннего футбола; давайте идентифицируем их с цифрами 1, 2, 3. Они расположены таким образом, что менеджер может удалить один из разделителей и объединить два из них, чтобы создать поле для семи сторон или обоих и сделать подачу для десяти сторон. Таким образом, поле 4 будет 1 + 2, поле 5 будет 2 + 3 и поле 6 будет 1 + 2 + 3 Это SQL код, который я имел (Это старый проект шахты написано в PHP и MySQL).Моделирование существующего отношения базы данных в GORM с составными ключами

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) 
; 

Я пытаюсь написать этот проект в Grails 3 с GORM по причинам обучения (я использую это в моей новой работе, а также, если это возможно, я хочу, чтобы воссоздать проект и предложить его для некоторых людей). Как вы можете видеть здесь, у меня есть два ограничения в field_component так родительский поле ссылается на существующих месторождениях в поле, но и так, что ребенок поле ссылается на существующих месторождениях в поле и также принадлежит к тому же объекту. Поэтому некоторые не могут добавить поле в качестве компонента из другого объекта.

В Grails я решил попытаться создать домены программно и позволить GORM создавать базу данных (я на самом деле боролся с этим, я всегда предпочитал начинать с БД и позволял этому руководить разработкой, но затем никогда не использовал ORM до), но у меня возникают проблемы, воссоздающие эти ограничения.

My table field_component был в основном таблицей соединений, поэтому я использую сопоставление hasMany с joinTable, но проблема в том, что с использованием идентификатора я не могу принудить второе ограничение, которое гарантирует, что зарегистрированный ребенок является частью такой же объект.

Вот мой 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 
    } 
} 

Я думал об использовании компонентного кода ключа (вместо идентификатора по умолчанию). Тогда я имел бы facility_id и internal_id в качестве первичного ключа, и я думаю, что я могу сослаться, что в joinTanble, как это:

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

, но я на самом деле не 100% уверен, что это будет работать. Объект_ид создан по соглашению в базе данных, но я не уверен, насколько умна GORM. Несмотря на это, я до сих пор не знаю, как я буду применять второе ограничение относительно поля, принадлежащего тому же объекту. Является ли это чем-то, что, может быть, я не должен беспокоиться, слишком усилие для выигрыша? Я могу поместить некоторые проверки при добавлении и сохранении поля, но с учетом базы данных это позволило бы ошибочным данным.

Любые мысли по этому поводу?

ответ

Смежные вопросы