У меня есть отношение к базе данных в старом проекте шахты , где у атлетического объекта есть поля для разных видов спорта. В основном футбол; пять - сторона. Некоторые из этих объектов имеют то, что я называю составными полями. Давайте возьмем пример. Объект '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. Несмотря на это, я до сих пор не знаю, как я буду применять второе ограничение относительно поля, принадлежащего тому же объекту. Является ли это чем-то, что, может быть, я не должен беспокоиться, слишком усилие для выигрыша? Я могу поместить некоторые проверки при добавлении и сохранении поля, но с учетом базы данных это позволило бы ошибочным данным.
Любые мысли по этому поводу?