powered by simpleCommunicator - 2.0.51     © 2025 Programmizd 02
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Что лучше: FK или триггеры проверки целостности?
63 сообщений из 63, показаны все 3 страниц
Что лучше: FK или триггеры проверки целостности?
    #39632855
V.Borzov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Здравствуйте,

Один умный человек говорил как-то, что чем создавать кучу FK на всё-всё-всё, лучше сделать кучу триггеров, проверяющих целостность ссылки. Я постеснялся спросить у него тогда, а чем это лучше. И с тех пор мучаюсь этим вопросом. Никак не могу понять, где потери, чем встроенный механизм проверок FK будет хуже, чем организация триггеров, которые будут делать, вроде бы, то же самое, но руками. Или умный человек был неправ?

Спасибо.
...
Рейтинг: 0 / 0
Что лучше: FK или триггеры проверки целостности?
    #39632863
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
V.Borzov, "умный" человек был неправ.
...
Рейтинг: 0 / 0
Что лучше: FK или триггеры проверки целостности?
    #39632868
Фотография kdv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
V.Borzov,

умный человек неправ. Триггер действует на уровне пользовательской транзакции. Поэтому он не способен обеспечить контроль целостности между конкурирующими транзакциями (он тупо не видит чужих изменений).
А FK и PK проверяется по индексу, который содержит все ключи всех версий записей, т.е. он вне транзакций.
...
Рейтинг: 0 / 0
Что лучше: FK или триггеры проверки целостности?
    #39632883
Фотография Старый плюшевый мишка
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kdvV.Borzov,

умный человек неправ. Триггер действует на уровне пользовательской транзакции. Поэтому он не способен обеспечить контроль целостности между конкурирующими транзакциями (он тупо не видит чужих изменений).
А FK и PK проверяется по индексу, который содержит все ключи всех версий записей, т.е. он вне транзакций.

Вооот. А теперь представим себе мастер-таблицу, скажем, статусов документов. Нуусс, скажем, счетов.

Новый
В работе
Оплачен
Отгружено
Закрыт

И таблицу этих самых счетов. Из пары мильёнчиков документов хотя бы. FK от которой по статусу кивает на эту мастер-таблицу. Которая никогда и никем редактироваться не будет. И запросы с условием на статус в where. Которые подхватят этот самый индекс. Особенно ищущие закрытые, лет эдак через 10 функлицирования предприятия. И прикинем сизифовы усилия сервера на регулярном ресторе этой базы при создании этого самого индекса.

Жил один еврей, так он сказал, что всё относительно. Как говорят highly likely - it depends. Сдаёццо мне, что слова умного человека вырваны из контекста. Хотя в общем случае, безусловно, FK рулит.
...
Рейтинг: 0 / 0
Что лучше: FK или триггеры проверки целостности?
    #39632884
Гаджимурадов Рустам
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А нефиг FK на 5 строк делать.

P.S. Топик не читал.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Что лучше: FK или триггеры проверки целостности?
    #39632886
Фотография Старый плюшевый мишка
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Гаджимурадов РустамА нефиг FK на 5 строк делать.

P.S. Топик не читал.


Если эти пять строк могут активно меняться - вполне так себе фиг. Правда лично я такой задачи придумать не могу :)
...
Рейтинг: 0 / 0
Что лучше: FK или триггеры проверки целостности?
    #39632891
Гаджимурадов Рустам
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вы, кстати, "универсальные" справочники практиковали?
Это когда несколько однотипных справочников
объединяются по вертикали - ID, Ref_ID, Value, ... ?
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Что лучше: FK или триггеры проверки целостности?
    #39632950
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Старый плюшевый мишкаА теперь представим себе мастер-таблицу, скажем, статусов документов. Нуусс, скажем, счетов.

Новый
В работе
Оплачен
Отгружено
Закрыт
NEW, IN_WORK, PAID, SHIPPED, CLOSED - ASCII символы этих слов слева направо легко умещаются в BIGINT от старшего байта к младшему, прекрасно сортируются и интерпретируются без всяких мастер-таблиц. Остается лишь прописать соответствующие числовые константы в ограничении CHECK соответствующего поля и создать по этому полю индекс.
...
Рейтинг: 0 / 0
Что лучше: FK или триггеры проверки целостности?
    #39632973
Фотография DarkMaster
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Гаджимурадов РустамВы, кстати, "универсальные" справочники практиковали?
Это когда несколько однотипных справочников
объединяются по вертикали - ID, Ref_ID, Value, ... ?


Когда-то давно делали что-то похожее в мелком проекте. Чисто из интереса. Итог - закопали поглубже, ибо неудобно от слова совсем.
...
Рейтинг: 0 / 0
Что лучше: FK или триггеры проверки целостности?
    #39632976
Гаджимурадов Рустам
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DarkMaster> неудобно от слова совсем.

А что именно было неудобно?
Разработка, сопровождение, иное?
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Что лучше: FK или триггеры проверки целостности?
    #39632980
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Гаджимурадов РустамА что именно было неудобно?
Разработка, сопровождение, иное?Неудобно потому, что такой справочник лучше делать древовидным, когда первый уровень древа определяет тип справочника, а второй - элементы справочника. При использовании значений из такого справочника в поле таблицы придётся делать обвязку на триггере добавления/изменения. "Овчинка выделки не стоит".
...
Рейтинг: 0 / 0
Что лучше: FK или триггеры проверки целостности?
    #39632991
m7m
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rdb_dev.... При использовании значений из такого справочника в поле таблицы придётся делать обвязку на триггере добавления/изменения. "Овчинка выделки не стоит".
о какой обвязке речь?
...
Рейтинг: 0 / 0
Что лучше: FK или триггеры проверки целостности?
    #39632998
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
m7m, о такой, которая будет проверять - входит ли значение поля в соответствующий диапазон ключей, относящийся к конкретному типу справочника, т.е. проверять идентификатор узла соответствующего ключа.
...
Рейтинг: 0 / 0
Что лучше: FK или триггеры проверки целостности?
    #39632999
Фотография DarkMaster
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Гаджимурадов РустамDarkMaster> неудобно от слова совсем.

А что именно было неудобно?
Разработка, сопровождение, иное?


Ну то, что запросы становятся развесистыми - уже минус. Ну и постоянные кастование. Если честно - помню только общие нехорошие впечатления, но если очень интересно - могу покопаться в архивах - исходники где-то должны быть.
...
Рейтинг: 0 / 0
Что лучше: FK или триггеры проверки целостности?
    #39633002
fraks
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rdb_devГаджимурадов РустамА что именно было неудобно?
Разработка, сопровождение, иное?Неудобно потому, что такой справочник лучше делать древовидным, когда первый уровень древа определяет тип справочника, а второй - элементы справочника.

Есть такое дерево. Тоже задумывалось "для всего". Но в итоге там только справочник товаров, все остальное туда так и не засунул т.к. перестал понимать зачем.
...
Рейтинг: 0 / 0
Что лучше: FK или триггеры проверки целостности?
    #39633003
KreatorXXI
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
У нас есть такой "универсальный" справочник. Вместо дерева используется идентификатор типа справочника. Проблема (у нас) в том, что в зависимости от этого типа нужна разная логика в поведении. Поэтому у нас она на клиенте. Допустим для одного справочника нужно каскадное удаление, для другого не нужно. Есть ещё проблемки. Например, просто пишем запрос по связанным справочникам и в запросе, допустим, 6-8 джойнов по одной таблице. Нечитаемо. И у меня есть подозрения в скорости таких запросов, хотя Влад сказал, что это вряд ли.
...
Рейтинг: 0 / 0
Что лучше: FK или триггеры проверки целостности?
    #39633028
fraks
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
KreatorXXIНапример, просто пишем запрос по связанным справочникам и в запросе, допустим, 6-8 джойнов по одной таблице. Нечитаемо.

Через алиасы получается довольно читаемо.
Однако все равно не отвечает на вопрос - почему не в отдельных таблицах.
...
Рейтинг: 0 / 0
Что лучше: FK или триггеры проверки целостности?
    #39633044
m7m
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Гаджимурадов Рустам,

Да
Но это были совсем простые справочники, фактически не имеющие никакой "расчетной" нагрузки, ну вроде вот такого
... здесь код, кто и когда создал запись, кто и когда последний раз её изменил
шифр
наименование
краткое наименование
....здесь еще несколько полей такого-же плана
примечание

И таки по факту для разработчиков это был "деревянный двухуровневый" справочник, для пользователей
это были полноценные отдельные справочники.
Из достоинств - очевидное при появлении нового "справочника" мизер телодвижений, добавить строку в первый уровень и в меню дабы он был доступен как отдельный справочник.

Из недостатков - тоже очевидное,то что можно назвать "не додумал" (не полное знание предметной области, расширение круга решаемых задач), и оказывается справочник надо либо выносить в отдельную таблицу либо добавлять поля в существующую именно для этого справочника, либо ....

И собственно недостаток превысил достоинство

что касается именно "обвязки на триггере" - нам она была не нужна, ну просто из-за
придерживания "идеологии" - в "сырой документ" вводите всё что хотите и как хотите
а в обработку пойдет только тот документ в котором нет "ошибок", и проверка "на соответствие диапазону ключей" это та самое меньшее из контроля
...
Рейтинг: 0 / 0
Что лучше: FK или триггеры проверки целостности?
    #39633060
Гаджимурадов Рустам
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DarkMaster> Ну то, что запросы становятся развесистыми - уже минус.

Если мы говорим об одном и том же, то по сути добавляется только
одно (или два) условия в where (к одному/двум полям одной таблицы).
Не так уж и развесисто. С учетом нормальных алиасов как подсказали
выше - и читаемость особо не страдает.

> Ну и постоянные кастование.

Это ты про Value1, Value2 и пр. универсальные поля?

> Если честно - помню только общие нехорошие впечатления,

Меня интересуют впечатления, неизвестные грабли и пр,
исходники как раз малоинтересны, там сложностей нет.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Что лучше: FK или триггеры проверки целостности?
    #39633064
Гаджимурадов Рустам
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
m7m> Но это были совсем простые справочники, фактически
m7m> не имеющие никакой "расчетной" нагрузки

Ну я и говорю о простых справочниках, о которых выше речь
зашла, сложные-то понятно каждый в своей отдельной таблице.
Как справочник может иметь расчетную нагрузку не очень понял.

> Из недостатков - тоже очевидное,то что можно назвать "не додумал"
> (не полное знание предметной области, расширение круга решаемых задач)
>
> И собственно недостаток превысил достоинство

Ясно, спасибо. Иных недостатков, подводных камней не замечали?
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Что лучше: FK или триггеры проверки целостности?
    #39633072
m7m
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Гаджимурадов РустамКак справочник может иметь расчетную нагрузку не очень понял.

Наверное я неправильно написал, имелось ввиду что-то в вроде вот такого
"коэффициент перерасчета из одной единицы измерения в другую", ну и тому подобное
Гаджимурадов РустамИных недостатков, подводных камней не замечали?
Нет, не вспоминается
...
Рейтинг: 0 / 0
Что лучше: FK или триггеры проверки целостности?
    #39633074
Фотография DarkMaster
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Гаджимурадов Рустам С учетом нормальных алиасов как подсказали
выше - и читаемость особо не страдает.


Это когда их мало. Даже с альясами при "широкой" выборке запрос превращается в лес из JOIN`ов. Не удобно, потому что при возврате через месяц к этому запросу - нужно делать на лишнюю операцию больше, чтобы "раскрутить" запрос в голове и понять, куда какой справочник лепится.

Гаджимурадов Рустам> Ну и постоянные кастование.

Это ты про Value1, Value2 и пр. универсальные поля?


Про них.
...
Рейтинг: 0 / 0
Что лучше: FK или триггеры проверки целостности?
    #39633086
m7m
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DarkMasterЭто когда их мало. Даже с альясами при "широкой" выборке запрос превращается в лес из JOIN`ов. Не удобно, потому что при возврате через месяц к этому запросу - нужно делать на лишнюю операцию больше, чтобы "раскрутить" запрос в голове и понять, куда какой справочник лепится.

Я немного не понял, ведь в любом случае независимо от того справочники в одной таблице или в разных "лес из JOIN`ов" останется, или я не прав?
...
Рейтинг: 0 / 0
Что лучше: FK или триггеры проверки целостности?
    #39633140
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Гаджимурадов РустамНу я и говорю о простых справочниках, о которых выше речь
зашла, сложные-то понятно каждый в своей отдельной таблице.
Как справочник может иметь расчетную нагрузку не очень понял.
Вот как-то так...
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
183.
184.
185.
186.
187.
188.
189.
190.
191.
192.
193.
194.
195.
196.
197.
-- Не осуждайте за использование зарезервированных слов в именах доменов :)
CREATE DOMAIN SMALL_ID AS SMALLINT;
CREATE DOMAIN UNITAG AS VARCHAR(31) CHARACTER SET UTF8;
CREATE DOMAIN NAME AS VARCHAR(200) CHARACTER SET UTF8;

/*
 * --= Справочник размерностей =--
 * "id"       - Идентификатор размерности;
 * "main_id"  - Внешний ключ к идентификатору базовой размерности
 *              мастер-таблицы;
 * "base"     - Множитель базовой размерности;
 * "power"    - Степень множителя базовой размерности;
 * "mark"     - Метка размерности;
 * "name"     - Наименование размерности;
 */
CREATE TABLE "dims" (
    "id"      SMALL_ID NOT NULL,
    "main_id" SMALL_ID DEFAULT 0,
    "base"    INTEGER DEFAULT 10 NOT NULL,
    "power"   SMALLINT DEFAULT 0 NOT NULL,
    "mark"    UNITAG NOT NULL,
    "name"    NAME NOT NULL,
  CONSTRAINT "dims__pk" PRIMARY KEY ("id"),
  CONSTRAINT "dims__fk__self" FOREIGN KEY ("main_id")
    REFERENCES "dims" ("id") ON UPDATE CASCADE ON DELETE SET DEFAULT,
  CONSTRAINT "dims__uq" UNIQUE ("main_id", "base", "power", "mark")
);
COMMENT ON TABLE  "dims" IS 'Справочник размерностей величин';
COMMENT ON COLUMN "dims"."id" IS 'Идентификатор размерности';
COMMENT ON COLUMN "dims"."main_id"
  IS 'Ключ мастер-таблицы идентификатора базовой размерности';
COMMENT ON COLUMN "dims"."base"
  IS 'Множитель базовой размерности';
COMMENT ON COLUMN "dims"."power" IS 'Степень множителя базовой размерности';
COMMENT ON COLUMN "dims"."mark" IS 'Метка размерности';
COMMENT ON COLUMN "dims"."name" IS 'Наименование размерности';

REVOKE ALL ON TABLE "dims" FROM PUBLIC, ROLE USERS;
GRANT SELECT, REFERENCES("id") ON TABLE "dims" TO ROLE USERS;


CREATE GENERATOR "dims__GEN";
COMMIT WORK;


/*
 * Триггер получения идентификатора размерности величины
 * для новой записи
 */
SET TERM ^;
CREATE OR ALTER TRIGGER "dims__TR_BI"
  FOR "dims"
  ACTIVE
  BEFORE INSERT
  POSITION 0
AS
BEGIN
  IF (NOT(NEW."id" IS NOT NULL
      AND NEW."id" <= GEN_ID("dims__GEN", 0))) THEN
    NEW."id" = GEN_ID("dims__GEN", 1);
END^
SET TERM ;^
COMMIT WORK;

/*
SET TERM ^;
CREATE OR ALTER PROCEDURE oneRow
  RETURNS ("tmstmp" TIMESTAMP)
AS
BEGIN
  "tmstmp" = CURRENT_TIMESTAMP;
  SUSPEND;
END^
SET TERM ;^
GRANT EXECUTE ON PROCEDURE oneRow TO PUBLIC;
COMMIT WORK;
*/


DELETE FROM "dims";
SET GENERATOR "dims__GEN" TO 56;
INSERT INTO "dims"
    ("id", "main_id", "base", "power", "mark", "name")
        SELECT  0, NULL,   0,  0, '',    '' FROM oneRow
  UNION SELECT  1,    0,  10,  0, 'В',   'Вольт' FROM oneRow
  UNION SELECT  2,    1,  10,  3, 'кВ',  'Киловольт' FROM oneRow
  UNION SELECT  3,    1,  10,  6, 'МВ',  'Мегавольт' FROM oneRow
  UNION SELECT  4,    0,  10,  0, 'Ом',  'Ом' FROM oneRow
  UNION SELECT  5,    4,  10,  3, 'кОм', 'Килоом' FROM oneRow
  UNION SELECT  6,    0,  10,  0, 'А',   'Ампер' FROM oneRow
  UNION SELECT  7,    6,  10,  3, 'кА',  'Килоампер' FROM oneRow
  UNION SELECT  8,    0,  10,  0, 'Вт',  'Ватт' FROM oneRow
  UNION SELECT  9,    8,  10,  3, 'кВт', 'Киловатт' FROM oneRow
  UNION SELECT 10,    8,  10,  6, 'МВт', 'Мегаватт' FROM oneRow
  UNION SELECT 11,    8,  10,  9, 'ГВт', 'Гигаватт' FROM oneRow
  UNION SELECT 12,    0,  10,  0, 'Дж',  'Джоуль' FROM oneRow
  UNION SELECT 13,   12,  10,  3, 'кДж', 'Килоджоуль' FROM oneRow
  UNION SELECT 14,   12,  10,  6, 'МДж', 'Мегаджоуль' FROM oneRow
  UNION SELECT 15,    0,  10,  0, 'м',   'Метр' FROM oneRow
  UNION SELECT 16,   15,  10, -3, 'мм',  'Миллиметр' FROM oneRow
  UNION SELECT 17,   15,  10, -6, 'мкм', 'Микрометр' FROM oneRow
  UNION SELECT 18,   15,  10,  3, 'км',  'Километр' FROM oneRow
  UNION SELECT 19,    0,  10, -3, 'г',   'Грамм' FROM oneRow
  UNION SELECT 20,   19,  10, -6, 'мг',  'Миллиграмм' FROM oneRow
  UNION SELECT 21,   19,  10,  0, 'кг',  'Килограмм' FROM oneRow
  UNION SELECT 22,   19,  10,  3, 'т',   'Тонна' FROM oneRow
  UNION SELECT 23,    0,  60,  0, 'с',   'Секунда' FROM oneRow
  UNION SELECT 24,   23,  60,  1, 'мин', 'Минута' FROM oneRow
  UNION SELECT 25,   23,  60,  2, 'ч',   'Час' FROM oneRow
  UNION SELECT 26,   23, 86400,1, 'сут', 'Сутки' FROM oneRow
  UNION SELECT 27,   23,  10, -3, 'мс',  'Миллисекунда' FROM oneRow
  UNION SELECT 28,   23,  10, -6, 'мкс', 'Микросекунда' FROM oneRow
  UNION SELECT 29,    0,  10,  0, 'Гц',  'Герц' FROM oneRow
  UNION SELECT 30,   29,  10,  3, 'кГц', 'Килогерц' FROM oneRow
  UNION SELECT 31,   29,  10,  6, 'МГц', 'Мегагерц' FROM oneRow
  UNION SELECT 32,   29,  10,  9, 'ГГц', 'Гигагерц' FROM oneRow
  UNION SELECT 33,    0,   1,  0, '°C',  'Градус Цельсия' FROM oneRow
  UNION SELECT 34,    0,   1,  0, '°',   'Градус' FROM oneRow
  UNION SELECT 35,   34,  60, -1, '''',  'Угловая минута' FROM oneRow
  UNION SELECT 36,   34,  60, -2, '"',   'Угловая секунда' FROM oneRow
  UNION SELECT 37,    0,  10,  0, '%',   'Процент' FROM oneRow
  UNION SELECT 38,    0,  10,  0, 'Вар',  'Вар' FROM oneRow
  UNION SELECT 39,   38,  10,  3, 'кВар', 'Киловар' FROM oneRow
  UNION SELECT 40,   38,  10,  6, 'МВар', 'Мегавар' FROM oneRow
  UNION SELECT 41,   38,  10, -3, 'мВар', 'Милливар' FROM oneRow
  UNION SELECT 42,    0,  10,  0, 'ВА',   'Вольт-Ампер' FROM oneRow
  UNION SELECT 43,   42,  10,  3, 'кВА',  'Киловольт-Ампер' FROM oneRow
  UNION SELECT 44,   42,  10,  6, 'МВА',  'Мегавольт-Ампер' FROM oneRow
  UNION SELECT 45,   42,  10, -3, 'мВА',  'Милливольт-Ампер' FROM oneRow
  UNION SELECT 46,    0,  10,  0, 'раз',      'Раз' FROM oneRow
  UNION SELECT 47,   46,  10,  3, 'тыс.раз',  'Тысяч раз' FROM oneRow
  UNION SELECT 48,   46,  10,  6, 'млн.раз',  'Миллион раз' FROM oneRow
  UNION SELECT 49,   46,  10,  9, 'млрд.раз', 'Миллиард раз' FROM oneRow
  UNION SELECT 50,    0,  10,  0, 'шт.',      'Штук' FROM oneRow
  UNION SELECT 51,   50,  10,  3, 'тыс.шт.',  'Тысяч штук' FROM oneRow
  UNION SELECT 52,   50,  10,  6, 'млн.шт.',  'Миллион штук' FROM oneRow
  UNION SELECT 53,    0,  10,  0, 'бит/с',    'Бит в секунду' FROM oneRow
  UNION SELECT 54,   53,  10,  3, 'кбит/с',   'Килобит в секунду' FROM oneRow
  UNION SELECT 55,   53,  10,  6, 'Мбит/с',   'Мегабит в секунду' FROM oneRow
  UNION SELECT 56,    0,  10,  0, 'м/с',      'Метр в секунду' FROM oneRow;
COMMIT WORK;



/*
 * Представление долей размерностей по базовой размерности
 *
 * для отображения выбора долей величин измерений
 * и упрощения преобразований долей размерностей
 */
CREATE OR ALTER VIEW "dims__quotList"
AS
WITH RECURSIVE dims AS
(
  SELECT "main_id", "id", "base", "power",
      "mark" AS "main_mark", "mark", "name"
    FROM "dims"
    WHERE "main_id" = 0
  UNION ALL
  SELECT b."main_id", b."id", b."base", b."power",
      a."main_mark", b."mark", b."name"
    FROM "dims" b
      INNER JOIN dims a ON b."main_id" = a."id"
)
SELECT "main_id", "id", "base", "power", "main_mark", "mark", "name"
  FROM dims;


/*
 * Возвращает список долей величин по базовой размерности, отсортированный
 * по имени базовой размерности, базовому коэффициенту и его степени
 * относительно базовой размерности
 */
SET TERM ^;
CREATE OR ALTER PROCEDURE "dims__getQuotList"
  RETURNS
  (
    "id"      SMALL_ID,
    "name"    NAME
  )
AS
BEGIN
  FOR
      SELECT "id", "name"
        FROM "dims__quotList"
        ORDER BY "main_mark", "base", "power"
        INTO: "id", "name"
    DO
      SUSPEND;
END^
SET TERM ;^

GRANT SELECT ON "dims__quotList" TO PROCEDURE "dims__getList";
GRANT SELECT, REFERENCES ("id") ON TABLE "dims"
  TO PROCEDURE "dims__quotList";
COMMIT WORK;
/* ----------------------------------------------------------------- */

...
Рейтинг: 0 / 0
Что лучше: FK или триггеры проверки целостности?
    #39633152
KreatorXXI
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я вот приводил пример леса джойнов:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
select a.longname, b.longname, c.shortname, d.longname, e.longname, f.shortname
from sprav a
        inner join sprav b on b.id2=a.id and b.priznak=2
        inner join sprav c on c.id2=b.id and c.priznak=3
        inner join sprav d on d.id3=a.id2  and d.priznak=4
        inner join sprav e on e.id2=d.id and e.priznak=5
        inner join sprav f on f.id3=e.id and f.priznak=6
where a.priznak=1


Ну нечитаемо совсем. Если только комментарии к каждой строке...
...
Рейтинг: 0 / 0
Что лучше: FK или триггеры проверки целостности?
    #39633153
Фотография DarkMaster
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
m7m,

Да, но легче читать запрос когда подвязываются таблицы-справочники, а не 1 справочник много раз. Ну это лично для меня.
...
Рейтинг: 0 / 0
Что лучше: FK или триггеры проверки целостности?
    #39633169
Фотография Старый плюшевый мишка
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Гаджимурадов РустамВы, кстати, "универсальные" справочники практиковали?
Это когда несколько однотипных справочников
объединяются по вертикали - ID, Ref_ID, Value, ... ?


Нет. Чем проще и каноничнее структура, тем проще жизнь. Имхо.
...
Рейтинг: 0 / 0
Что лучше: FK или триггеры проверки целостности?
    #39633174
Фотография Старый плюшевый мишка
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rdb_devСтарый плюшевый мишкаА теперь представим себе мастер-таблицу, скажем, статусов документов. Нуусс, скажем, счетов.

Новый
В работе
Оплачен
Отгружено
Закрыт
NEW, IN_WORK, PAID, SHIPPED, CLOSED - ASCII символы этих слов слева направо легко умещаются в BIGINT от старшего байта к младшему, прекрасно сортируются и интерпретируются без всяких мастер-таблиц. Остается лишь прописать соответствующие числовые константы в ограничении CHECK соответствующего поля и создать по этому полю индекс.

Речь не о том, что во что впихуемо. За "создать по этому полю индекс" - двойка. Ты ничего не понял.
...
Рейтинг: 0 / 0
Что лучше: FK или триггеры проверки целостности?
    #39633177
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Старый плюшевый мишкаЗа "создать по этому полю индекс" - двойка. Ты ничего не понял.Обоснуешь? Объяснишь?
...
Рейтинг: 0 / 0
Что лучше: FK или триггеры проверки целостности?
    #39633179
WildSery
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Пробовал.

Удобно использовать для простых перечислений, которые состоят только из наименования и ещё пары "базовых" признаков, типа пометки удаления, признака группы и родителя/иерархии.

Собственно, и всё.
Остальное признано нецелесообразным.
...
Рейтинг: 0 / 0
Что лучше: FK или триггеры проверки целостности?
    #39633190
Фотография Старый плюшевый мишка
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rdb_devСтарый плюшевый мишкаЗа "создать по этому полю индекс" - двойка. Ты ничего не понял.Обоснуешь? Объяснишь?

Да раком сервак встанет, если попытается на заметных объёмах его в запросах использовать. Причём не во всех запросах, а в зависимости от количества дубликатов искомого значения. Можно год не наступить на мину, а потом кааак бабахнет! И ресторить сутками будет, строя этот индекс. Весь сыр-бор с отказом от FK именно для того, чтобы от него избавиться.
...
Рейтинг: 0 / 0
Что лучше: FK или триггеры проверки целостности?
    #39633202
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Старый плюшевый мишкаДа раком сервак встанет, если попытается на заметных объёмах его в запросах использовать. Причём не во всех запросах, а в зависимости от количества дубликатов искомого значения. Можно год не наступить на мину, а потом кааак бабахнет! И ресторить сутками будет, строя этот индекс. Весь сыр-бор с отказом от FK именно для того, чтобы от него избавиться.Чот я не пойму... В FK у тебя суррогатный ключ, например тот же BIGINT, по которому, в случае FK, будет построен индекс, но ко всему прочему, еще будет осуществляться проверка на наличие соответствующего ключа в мастер-таблице. Так почему в случае моих константных значений BIGINT сервер встанет раком, а в случае FK-PK - не встанет?
...
Рейтинг: 0 / 0
Что лучше: FK или триггеры проверки целостности?
    #39633204
pastor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Гаджимурадов РустамDarkMaster> Ну то, что запросы становятся развесистыми - уже минус.

Если мы говорим об одном и том же, то по сути добавляется только
одно (или два) условия в where (к одному/двум полям одной таблицы).
Не так уж и развесисто. С учетом нормальных алиасов как подсказали
выше - и читаемость особо не страдает.

> Ну и постоянные кастование.

Это ты про Value1, Value2 и пр. универсальные поля?

> Если честно - помню только общие нехорошие впечатления,

Меня интересуют впечатления, неизвестные грабли и пр,
исходники как раз малоинтересны, там сложностей нет.


Для справчоников, создаваемых пользователями.
Т.е. создается критерий "размер ноги", к нему набор допустимых значений
потом "размер головы", "длина лыж", "длина палок"

лукапы делать не сильно удобно. приходится генерить на ходу.

все значения текстовые.

справочники, которые не могут редактироваться пользователями - "пол" - забиваются в домены ( M F U), расшифровки - в справочник описания доменов (F - Женский)

были попытки создания древовидной (точнее иерархической) структуры документов, сущностей и пр, но не взлетело. канонические структуры оказались быстрее в разработке, работе и сопровождении.
...
Рейтинг: 0 / 0
Что лучше: FK или триггеры проверки целостности?
    #39633236
Фотография Старый плюшевый мишка
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rdb_devСтарый плюшевый мишкаДа раком сервак встанет, если попытается на заметных объёмах его в запросах использовать. Причём не во всех запросах, а в зависимости от количества дубликатов искомого значения. Можно год не наступить на мину, а потом кааак бабахнет! И ресторить сутками будет, строя этот индекс. Весь сыр-бор с отказом от FK именно для того, чтобы от него избавиться.Чот я не пойму... В FK у тебя суррогатный ключ, например тот же BIGINT, по которому, в случае FK, будет построен индекс, но ко всему прочему, еще будет осуществляться проверка на наличие соответствующего ключа в мастер-таблице. Так почему в случае моих константных значений BIGINT сервер встанет раком, а в случае FK-PK - не встанет?

Ой фсё...
...
Рейтинг: 0 / 0
Что лучше: FK или триггеры проверки целостности?
    #39633237
Фотография Старый плюшевый мишка
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Старый плюшевый мишкаrdb_devпропущено...
Чот я не пойму... В FK у тебя суррогатный ключ, например тот же BIGINT, по которому, в случае FK, будет построен индекс, но ко всему прочему, еще будет осуществляться проверка на наличие соответствующего ключа в мастер-таблице. Так почему в случае моих константных значений BIGINT сервер встанет раком, а в случае FK-PK - не встанет?

Ой фсё...

Подробнее - я отвечаю за то, что я пишу, а не за то, что ты читаешь :)
...
Рейтинг: 0 / 0
Что лучше: FK или триггеры проверки целостности?
    #39633262
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Старый плюшевый мишкаПодробнее - я отвечаю за то, что я пишу, а не за то, что ты читаешь :)😆
...
Рейтинг: 0 / 0
Что лучше: FK или триггеры проверки целостности?
    #39633292
WildSery
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rdb_dev,

Ты поищи, поищи, где о FK такое написано.
Речь шла об индексе, и никакой разницы, FK он или не FK.
...
Рейтинг: 0 / 0
Что лучше: FK или триггеры проверки целостности?
    #39633429
Гаджимурадов Рустам
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DarkMaster> Да, но легче читать запрос когда подвязываются таблицы-справочники,
DarkMaster> а не 1 справочник много раз. Ну это лично для меня.

С алиасом разницы практически никакой нет. Но это вкусовщина, в любом случае.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Что лучше: FK или триггеры проверки целостности?
    #39633430
Гаджимурадов Рустам
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В общем, всем спасибо за мнения и впечатления.

pastor> были попытки создания древовидной (точнее иерархической)
pastor> структуры документов, сущностей и пр, но не взлетело

В смысле некая EAV-light или тот же справочник, но ещё и
древовидный (в чём его древовидность-то заключается) ?
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Что лучше: FK или триггеры проверки целостности?
    #39633449
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
WildSery, бывает, я, порой, не догоняю о чем речь и потому переспрашиваю. И?
...
Рейтинг: 0 / 0
Что лучше: FK или триггеры проверки целостности?
    #39633488
m7m
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
KreatorXXIЯ вот приводил пример леса джойнов:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
select a.longname, b.longname, c.shortname, d.longname, e.longname, f.shortname
from sprav a
        inner join sprav b on b.id2=a.id and b.priznak=2
        inner join sprav c on c.id2=b.id and c.priznak=3
        inner join sprav d on d.id3=a.id2  and d.priznak=4
        inner join sprav e on e.id2=d.id and e.priznak=5
        inner join sprav f on f.id3=e.id and f.priznak=6
where a.priznak=1



Ну нечитаемо совсем. Если только комментарии к каждой строке...
Конечно нечитаемо, ты один справочник сам с собой связываешь
а если вот такое
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
select Z......, A.Longname as Areaname, B.Longname as BoilerName, C.Shortname as Claimshortname,
       D.Longname as Districtname, Dp.Longname as Departmentname,
  from Doc Z
    join Sprav A on A.Id = Z.Area
    join Sprav B on B.Id = Z.Boiler
    join Sprav C on C.Id = Z.Claim
    join Sprav Di on Di.Id = Z.District
    join Sprav Dp on Dp.Id = Z.Department
    .......................
  where..................  


так совсем другой вид
...
Рейтинг: 0 / 0
Что лучше: FK или триггеры проверки целостности?
    #39633543
WildSery
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rdb_dev,

Моё дело метёлкой махать, а не подталкивать отстающих.
...
Рейтинг: 0 / 0
Что лучше: FK или триггеры проверки целостности?
    #39633592
KreatorXXI
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
m7m,

Я привёл как-раз свой пример, где "универсальность" справочников доведена до маразма. У нас именно так они и перевязаны.
...
Рейтинг: 0 / 0
Что лучше: FK или триггеры проверки целостности?
    #39633662
Arioch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
m7m
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
select Z......, A.Longname as Areaname, B.Longname as BoilerName, C.Shortname as Claimshortname,
       D.Longname as Districtname, Dp.Longname as Departmentname,
  from Doc Z
    join Sprav A on A.Id = Z.Area
    join Sprav B on B.Id = Z.Boiler
    join Sprav C on C.Id = Z.Claim
    join Sprav Di on Di.Id = Z.District
    join Sprav Dp on Dp.Id = Z.Department
    .......................
  where..................  



Откуда требование ещё и глобального одного-на-всю-БД источника ID для всех объектов

Чтобы не случилось, что например Z[1].Area = Z[8].District или Z[123].Department = Z[47].Claim
...
Рейтинг: 0 / 0
Что лучше: FK или триггеры проверки целостности?
    #39633665
Arioch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
KreatorXXI,

Такое ощущение, что вы там аналог Windows Registry замутили.

Наверное тогда как и в Windows надо было делить на две сущности, делать две таблицы.

1) дерево структуры, ноды
2) Key-Value значения, привязанные к конкретной ноде

Тогда ты сначала выбираешь ноду по первой таблице, а потом начинаешь е ней аттрибуты подтягивать?
...
Рейтинг: 0 / 0
Что лучше: FK или триггеры проверки целостности?
    #39633711
m7m
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AriochОткуда требование ещё и глобального одного-на-всю-БД источника ID для всех объектов
Ну не "одного-на-всю-БД источника ID" а только для тех кто в общем справочнике
Я не вижу в этом ничего плохого, а вот что увидел ты в этом плохого я не знаю
и мне это малость интересно
...
Рейтинг: 0 / 0
Что лучше: FK или триггеры проверки целостности?
    #39633713
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AriochТогда ты сначала выбираешь ноду по первой таблице, а потом начинаешь е ней аттрибуты подтягивать?Это уже динамическая ORM. :)
...
Рейтинг: 0 / 0
Что лучше: FK или триггеры проверки целостности?
    #39633765
KreatorXXI
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Arioch,

У нас сложней. Одна запись справочника может иметь до четырёх форейн-записей других справочников. Пока до четырёх. И деревянная структура тоже держится. Я когда увидел, что коллеги наваяли (я был новый), обалдел. Нет, связывать надо, никуда не деться. Но читабельность... Беру список признаков и разбираюсь часами. ИМХО, дурдом.
...
Рейтинг: 0 / 0
Что лучше: FK или триггеры проверки целостности?
    #39633767
Arioch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
m7m,

ненужная зависимость разных сущностей между собой - больше надо помнить и учитывать, а гибкость меньше

m7mтолько для тех кто в общем справочнике

в добавок еще ненужное усложнение системы

для одних объектов мы берем нoвые ID одним методом из одного хранилища, а для других - другим методом из других хранилищ. Это нужно всегда помнить и нигде не перепутать, вмеcто унификации кода.

А если потом какой-то изначально отдельный объект захочется внести в справочник?
...
Рейтинг: 0 / 0
Что лучше: FK или триггеры проверки целостности?
    #39633770
Arioch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
KreatorXXIОдна запись справочника может иметь до четырёх форейн-записей других справочников.

зачем?

KreatorXXIПока до четырёх.

ага, молотком и матерью всунуть шахматку на уровень структур RDBMS, потом грызть грааль "как сделать универсальный запрос, чтобы по любому из одинаковых столбцов...."
...
Рейтинг: 0 / 0
Что лучше: FK или триггеры проверки целостности?
    #39633773
Arioch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
KreatorXXIЯ вот приводил пример леса джойнов:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
select a.longname, b.longname, c.shortname, d.longname, e.longname, f.shortname
from sprav a
        inner join sprav b on b.id2=a.id and b.priznak=2
        inner join sprav c on c.id2=b.id and c.priznak=3
        inner join sprav d on d.id3=a.id2  and d.priznak=4
        inner join sprav e on e.id2=d.id and e.priznak=5
        inner join sprav f on f.id3=e.id and f.priznak=6
where a.priznak=1

Ну нечитаемо совсем.

Это потому что констант в Firebird нету

Ну а если насоздавать лишних сущностей?

Код: sql
1.
2.
3.
4.
5.
6.
7.
create view Sprav_Area as select * from Sprav where priznak=2;
create view Sprav_Boiler as select * from Sprav where priznak=3;
.....
select Z.* from Docs Z
  join Sprav_Area A on A.ID = Z.Area
  join Sprav_Boiler B on B.ID = Z.Boiler
.....



В пределе вывести всю работу с мега-справочником на раздельные вьюхи и потом превратить их в таблицы а мега-справочник грохнуть?
...
Рейтинг: 0 / 0
Что лучше: FK или триггеры проверки целостности?
    #39633784
Котовасия
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Гаджимурадов РустамВы, кстати, "универсальные" справочники практиковали?
Это когда несколько однотипных справочников
объединяются по вертикали - ID, Ref_ID, Value, ... ?

Практиковали. Все логические справочники в один засунули, назвали его TUPLE.
Только полей Value было много, и они были разнотипными: строка, целое, дата, момент времени и т.д.
Не открывайте, пожалуйста.
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
183.
184.
185.
186.
187.
188.
189.
190.
191.
192.
193.
194.
195.
196.
197.
198.
199.
200.
201.
202.
203.
204.
205.
206.
207.
208.
209.
210.
211.
212.
213.
214.
215.
216.
217.
218.
219.
220.
221.
222.
223.
224.
225.
226.
227.
228.
229.
230.
231.
232.
233.
234.
235.
236.
237.
238.
239.
240.
241.
242.
243.
244.
245.
246.
247.
248.
249.
250.
251.
252.
253.
254.
255.
256.
257.
258.
259.
260.
261.
262.
263.
264.
265.
266.
267.
268.
269.
270.
271.
272.
273.
274.
275.
276.
277.
278.
279.
280.
281.
282.
283.
284.
285.
286.
287.
288.
289.
290.
291.
292.
293.
294.
295.
296.
297.
298.
299.
300.
301.
302.
303.
304.
305.
306.
307.
308.
309.
310.
311.
312.
313.
314.
315.
316.
317.
318.
319.
320.
321.
322.
323.
324.
325.
326.
327.
328.
329.
330.
331.
332.
333.
334.
335.
336.
337.
338.
339.
340.
341.
342.
343.
344.
345.
346.
347.
348.
349.
350.
351.
352.
353.
354.
355.
356.
357.
358.
359.
360.
361.
362.
363.
364.
365.
366.
367.
368.
369.
370.
371.
372.
373.
374.
375.
376.
377.
378.
379.
380.
381.
382.
383.
384.
385.
386.
387.
388.
389.
390.
391.
392.
393.
394.
395.
396.
397.
398.
399.
400.
401.
402.
403.
404.
405.
406.
407.
408.
409.
410.
411.
412.
413.
414.
415.
416.
417.
418.
419.
420.
421.
422.
423.
424.
425.
426.
427.
428.
429.
430.
431.
432.
433.
434.
435.
436.
437.
438.
439.
440.
441.
442.
443.
444.
445.
446.
447.
448.
449.
450.
451.
452.
453.
454.
455.
456.
457.
458.
459.
460.
461.
462.
463.
464.
465.
466.
467.
468.
469.
470.
471.
472.
473.
474.
475.
476.
477.
478.
479.
480.
481.
482.
483.
484.
485.
486.
487.
488.
489.
490.
491.
492.
493.
494.
495.
496.
497.
498.
499.
500.
501.
502.
503.
504.
505.
506.
507.
508.
509.
510.
511.
512.
513.
514.
CREATE TABLE TUPLE (
    TUPLE_ID       T_ID NOT NULL /* T_ID = INTEGER */,
    COLLECTION_ID  T_ID NOT NULL /* T_ID = INTEGER */,
    VALUE_CODE     T_V_STR /* T_V_STR = VARCHAR(250) */,
    CREATE_MOMENT  T_V_MOMENT DEFAULT CURRENT_TIMESTAMP /* T_V_MOMENT = TIMESTAMP */,
    V_STR_00       T_V_STR /* T_V_STR = VARCHAR(250) */,
    V_STR_01       T_V_STR /* T_V_STR = VARCHAR(250) */,
    V_STR_02       T_V_STR /* T_V_STR = VARCHAR(250) */,
    V_STR_03       T_V_STR /* T_V_STR = VARCHAR(250) */,
    V_STR_04       T_V_STR /* T_V_STR = VARCHAR(250) */,
    V_STR_05       T_V_STR /* T_V_STR = VARCHAR(250) */,
    V_STR_06       T_V_STR /* T_V_STR = VARCHAR(250) */,
    V_STR_07       T_V_STR /* T_V_STR = VARCHAR(250) */,
    V_STR_08       T_V_STR /* T_V_STR = VARCHAR(250) */,
    V_STR_09       T_V_STR /* T_V_STR = VARCHAR(250) */,
    V_STR_10       T_V_STR /* T_V_STR = VARCHAR(250) */,
    V_STR_11       T_V_STR /* T_V_STR = VARCHAR(250) */,
    V_STR_12       T_V_STR /* T_V_STR = VARCHAR(250) */,
    V_STR_13       T_V_STR /* T_V_STR = VARCHAR(250) */,
    V_STR_14       T_V_STR /* T_V_STR = VARCHAR(250) */,
    V_STR_15       T_V_STR /* T_V_STR = VARCHAR(250) */,
    V_STR_16       T_V_STR /* T_V_STR = VARCHAR(250) */,
    V_STR_17       T_V_STR /* T_V_STR = VARCHAR(250) */,
    V_STR_18       T_V_STR /* T_V_STR = VARCHAR(250) */,
    V_STR_19       T_V_STR /* T_V_STR = VARCHAR(250) */,
    V_STR_20       T_V_STR /* T_V_STR = VARCHAR(250) */,
    V_STR_21       T_V_STR /* T_V_STR = VARCHAR(250) */,
    V_STR_22       T_V_STR /* T_V_STR = VARCHAR(250) */,
    V_STR_23       T_V_STR /* T_V_STR = VARCHAR(250) */,
    V_STR_24       T_V_STR /* T_V_STR = VARCHAR(250) */,
    V_STR_25       T_V_STR /* T_V_STR = VARCHAR(250) */,
    V_STR_26       T_V_STR /* T_V_STR = VARCHAR(250) */,
    V_STR_27       T_V_STR /* T_V_STR = VARCHAR(250) */,
    V_STR_28       T_V_STR /* T_V_STR = VARCHAR(250) */,
    V_STR_29       T_V_STR /* T_V_STR = VARCHAR(250) */,
    V_STR_30       T_V_STR /* T_V_STR = VARCHAR(250) */,
    V_STR_31       T_V_STR /* T_V_STR = VARCHAR(250) */,
    V_STR_32       T_V_STR /* T_V_STR = VARCHAR(250) */,
    V_STR_33       T_V_STR /* T_V_STR = VARCHAR(250) */,
    V_STR_34       T_V_STR /* T_V_STR = VARCHAR(250) */,
    V_STR_35       T_V_STR /* T_V_STR = VARCHAR(250) */,
    V_STR_36       T_V_STR /* T_V_STR = VARCHAR(250) */,
    V_STR_37       T_V_STR /* T_V_STR = VARCHAR(250) */,
    V_STR_38       T_V_STR /* T_V_STR = VARCHAR(250) */,
    V_STR_39       T_V_STR /* T_V_STR = VARCHAR(250) */,
    V_STR_40       T_V_STR /* T_V_STR = VARCHAR(250) */,
    V_STR_41       T_V_STR /* T_V_STR = VARCHAR(250) */,
    V_STR_42       T_V_STR /* T_V_STR = VARCHAR(250) */,
    V_STR_43       T_V_STR /* T_V_STR = VARCHAR(250) */,
    V_STR_44       T_V_STR /* T_V_STR = VARCHAR(250) */,
    V_STR_45       T_V_STR /* T_V_STR = VARCHAR(250) */,
    V_STR_46       T_V_STR /* T_V_STR = VARCHAR(250) */,
    V_STR_47       T_V_STR /* T_V_STR = VARCHAR(250) */,
    V_STR_48       T_V_STR /* T_V_STR = VARCHAR(250) */,
    V_STR_49       T_V_STR /* T_V_STR = VARCHAR(250) */,
    V_STR_50       T_V_STR /* T_V_STR = VARCHAR(250) */,
    V_STR_51       T_V_STR /* T_V_STR = VARCHAR(250) */,
    V_STR_52       T_V_STR /* T_V_STR = VARCHAR(250) */,
    V_STR_53       T_V_STR /* T_V_STR = VARCHAR(250) */,
    V_STR_54       T_V_STR /* T_V_STR = VARCHAR(250) */,
    V_STR_55       T_V_STR /* T_V_STR = VARCHAR(250) */,
    V_STR_56       T_V_STR /* T_V_STR = VARCHAR(250) */,
    V_STR_57       T_V_STR /* T_V_STR = VARCHAR(250) */,
    V_STR_58       T_V_STR /* T_V_STR = VARCHAR(250) */,
    V_STR_59       T_V_STR /* T_V_STR = VARCHAR(250) */,
    V_STR_60       T_V_STR /* T_V_STR = VARCHAR(250) */,
    V_STR_61       T_V_STR /* T_V_STR = VARCHAR(250) */,
    V_STR_62       T_V_STR /* T_V_STR = VARCHAR(250) */,
    V_STR_63       T_V_STR /* T_V_STR = VARCHAR(250) */,
    V_STR_64       T_V_STR /* T_V_STR = VARCHAR(250) */,
    V_STR_65       T_V_STR /* T_V_STR = VARCHAR(250) */,
    V_STR_66       T_V_STR /* T_V_STR = VARCHAR(250) */,
    V_STR_67       T_V_STR /* T_V_STR = VARCHAR(250) */,
    V_STR_68       T_V_STR /* T_V_STR = VARCHAR(250) */,
    V_STR_69       T_V_STR /* T_V_STR = VARCHAR(250) */,
    V_STR_70       T_V_STR /* T_V_STR = VARCHAR(250) */,
    V_STR_71       T_V_STR /* T_V_STR = VARCHAR(250) */,
    V_STR_72       T_V_STR /* T_V_STR = VARCHAR(250) */,
    V_STR_73       T_V_STR /* T_V_STR = VARCHAR(250) */,
    V_STR_74       T_V_STR /* T_V_STR = VARCHAR(250) */,
    V_STR_75       T_V_STR /* T_V_STR = VARCHAR(250) */,
    V_STR_76       T_V_STR /* T_V_STR = VARCHAR(250) */,
    V_STR_77       T_V_STR /* T_V_STR = VARCHAR(250) */,
    V_STR_78       T_V_STR /* T_V_STR = VARCHAR(250) */,
    V_STR_79       T_V_STR /* T_V_STR = VARCHAR(250) */,
    V_STR_80       T_V_STR /* T_V_STR = VARCHAR(250) */,
    V_STR_81       T_V_STR /* T_V_STR = VARCHAR(250) */,
    V_STR_82       T_V_STR /* T_V_STR = VARCHAR(250) */,
    V_STR_83       T_V_STR /* T_V_STR = VARCHAR(250) */,
    V_STR_84       T_V_STR /* T_V_STR = VARCHAR(250) */,
    V_STR_85       T_V_STR /* T_V_STR = VARCHAR(250) */,
    V_STR_86       T_V_STR /* T_V_STR = VARCHAR(250) */,
    V_STR_87       T_V_STR /* T_V_STR = VARCHAR(250) */,
    V_STR_88       T_V_STR /* T_V_STR = VARCHAR(250) */,
    V_STR_89       T_V_STR /* T_V_STR = VARCHAR(250) */,
    V_STR_90       T_V_STR /* T_V_STR = VARCHAR(250) */,
    V_STR_91       T_V_STR /* T_V_STR = VARCHAR(250) */,
    V_STR_92       T_V_STR /* T_V_STR = VARCHAR(250) */,
    V_STR_93       T_V_STR /* T_V_STR = VARCHAR(250) */,
    V_STR_94       T_V_STR /* T_V_STR = VARCHAR(250) */,
    V_STR_95       T_V_STR /* T_V_STR = VARCHAR(250) */,
    V_STR_96       T_V_STR /* T_V_STR = VARCHAR(250) */,
    V_STR_97       T_V_STR /* T_V_STR = VARCHAR(250) */,
    V_STR_98       T_V_STR /* T_V_STR = VARCHAR(250) */,
    V_STR_99       T_V_STR /* T_V_STR = VARCHAR(250) */,
    V_INT_00       T_V_INT /* T_V_INT = INTEGER */,
    V_INT_01       T_V_INT /* T_V_INT = INTEGER */,
    V_INT_02       T_V_INT /* T_V_INT = INTEGER */,
    V_INT_03       T_V_INT /* T_V_INT = INTEGER */,
    V_INT_04       T_V_INT /* T_V_INT = INTEGER */,
    V_INT_05       T_V_INT /* T_V_INT = INTEGER */,
    V_INT_06       T_V_INT /* T_V_INT = INTEGER */,
    V_INT_07       T_V_INT /* T_V_INT = INTEGER */,
    V_INT_08       T_V_INT /* T_V_INT = INTEGER */,
    V_INT_09       T_V_INT /* T_V_INT = INTEGER */,
    V_INT_10       T_V_INT /* T_V_INT = INTEGER */,
    V_INT_11       T_V_INT /* T_V_INT = INTEGER */,
    V_INT_12       T_V_INT /* T_V_INT = INTEGER */,
    V_INT_13       T_V_INT /* T_V_INT = INTEGER */,
    V_INT_14       T_V_INT /* T_V_INT = INTEGER */,
    V_INT_15       T_V_INT /* T_V_INT = INTEGER */,
    V_INT_16       T_V_INT /* T_V_INT = INTEGER */,
    V_INT_17       T_V_INT /* T_V_INT = INTEGER */,
    V_INT_18       T_V_INT /* T_V_INT = INTEGER */,
    V_INT_19       T_V_INT /* T_V_INT = INTEGER */,
    V_INT_20       T_V_INT /* T_V_INT = INTEGER */,
    V_INT_21       T_V_INT /* T_V_INT = INTEGER */,
    V_INT_22       T_V_INT /* T_V_INT = INTEGER */,
    V_INT_23       T_V_INT /* T_V_INT = INTEGER */,
    V_INT_24       T_V_INT /* T_V_INT = INTEGER */,
    V_INT_25       T_V_INT /* T_V_INT = INTEGER */,
    V_INT_26       T_V_INT /* T_V_INT = INTEGER */,
    V_INT_27       T_V_INT /* T_V_INT = INTEGER */,
    V_INT_28       T_V_INT /* T_V_INT = INTEGER */,
    V_INT_29       T_V_INT /* T_V_INT = INTEGER */,
    V_INT_30       T_V_INT /* T_V_INT = INTEGER */,
    V_INT_31       T_V_INT /* T_V_INT = INTEGER */,
    V_INT_32       T_V_INT /* T_V_INT = INTEGER */,
    V_INT_33       T_V_INT /* T_V_INT = INTEGER */,
    V_INT_34       T_V_INT /* T_V_INT = INTEGER */,
    V_INT_35       T_V_INT /* T_V_INT = INTEGER */,
    V_INT_36       T_V_INT /* T_V_INT = INTEGER */,
    V_INT_37       T_V_INT /* T_V_INT = INTEGER */,
    V_INT_38       T_V_INT /* T_V_INT = INTEGER */,
    V_INT_39       T_V_INT /* T_V_INT = INTEGER */,
    V_INT_40       T_V_INT /* T_V_INT = INTEGER */,
    V_INT_41       T_V_INT /* T_V_INT = INTEGER */,
    V_INT_42       T_V_INT /* T_V_INT = INTEGER */,
    V_INT_43       T_V_INT /* T_V_INT = INTEGER */,
    V_INT_44       T_V_INT /* T_V_INT = INTEGER */,
    V_INT_45       T_V_INT /* T_V_INT = INTEGER */,
    V_INT_46       T_V_INT /* T_V_INT = INTEGER */,
    V_INT_47       T_V_INT /* T_V_INT = INTEGER */,
    V_INT_48       T_V_INT /* T_V_INT = INTEGER */,
    V_INT_49       T_V_INT /* T_V_INT = INTEGER */,
    V_INT_50       T_V_INT /* T_V_INT = INTEGER */,
    V_INT_51       T_V_INT /* T_V_INT = INTEGER */,
    V_INT_52       T_V_INT /* T_V_INT = INTEGER */,
    V_INT_53       T_V_INT /* T_V_INT = INTEGER */,
    V_INT_54       T_V_INT /* T_V_INT = INTEGER */,
    V_INT_55       T_V_INT /* T_V_INT = INTEGER */,
    V_INT_56       T_V_INT /* T_V_INT = INTEGER */,
    V_INT_57       T_V_INT /* T_V_INT = INTEGER */,
    V_INT_58       T_V_INT /* T_V_INT = INTEGER */,
    V_INT_59       T_V_INT /* T_V_INT = INTEGER */,
    V_INT_60       T_V_INT /* T_V_INT = INTEGER */,
    V_INT_61       T_V_INT /* T_V_INT = INTEGER */,
    V_INT_62       T_V_INT /* T_V_INT = INTEGER */,
    V_INT_63       T_V_INT /* T_V_INT = INTEGER */,
    V_INT_64       T_V_INT /* T_V_INT = INTEGER */,
    V_INT_65       T_V_INT /* T_V_INT = INTEGER */,
    V_INT_66       T_V_INT /* T_V_INT = INTEGER */,
    V_INT_67       T_V_INT /* T_V_INT = INTEGER */,
    V_INT_68       T_V_INT /* T_V_INT = INTEGER */,
    V_INT_69       T_V_INT /* T_V_INT = INTEGER */,
    V_INT_70       T_V_INT /* T_V_INT = INTEGER */,
    V_INT_71       T_V_INT /* T_V_INT = INTEGER */,
    V_INT_72       T_V_INT /* T_V_INT = INTEGER */,
    V_INT_73       T_V_INT /* T_V_INT = INTEGER */,
    V_INT_74       T_V_INT /* T_V_INT = INTEGER */,
    V_INT_75       T_V_INT /* T_V_INT = INTEGER */,
    V_INT_76       T_V_INT /* T_V_INT = INTEGER */,
    V_INT_77       T_V_INT /* T_V_INT = INTEGER */,
    V_INT_78       T_V_INT /* T_V_INT = INTEGER */,
    V_INT_79       T_V_INT /* T_V_INT = INTEGER */,
    V_INT_80       T_V_INT /* T_V_INT = INTEGER */,
    V_INT_81       T_V_INT /* T_V_INT = INTEGER */,
    V_INT_82       T_V_INT /* T_V_INT = INTEGER */,
    V_INT_83       T_V_INT /* T_V_INT = INTEGER */,
    V_INT_84       T_V_INT /* T_V_INT = INTEGER */,
    V_INT_85       T_V_INT /* T_V_INT = INTEGER */,
    V_INT_86       T_V_INT /* T_V_INT = INTEGER */,
    V_INT_87       T_V_INT /* T_V_INT = INTEGER */,
    V_INT_88       T_V_INT /* T_V_INT = INTEGER */,
    V_INT_89       T_V_INT /* T_V_INT = INTEGER */,
    V_DATE_00      T_V_DATE /* T_V_DATE = DATE */,
    V_DATE_01      T_V_DATE /* T_V_DATE = DATE */,
    V_DATE_02      T_V_DATE /* T_V_DATE = DATE */,
    V_DATE_03      T_V_DATE /* T_V_DATE = DATE */,
    V_DATE_04      T_V_DATE /* T_V_DATE = DATE */,
    V_DATE_05      T_V_DATE /* T_V_DATE = DATE */,
    V_DATE_06      T_V_DATE /* T_V_DATE = DATE */,
    V_DATE_07      T_V_DATE /* T_V_DATE = DATE */,
    V_DATE_08      T_V_DATE /* T_V_DATE = DATE */,
    V_DATE_09      T_V_DATE /* T_V_DATE = DATE */,
    V_DATE_10      T_V_DATE /* T_V_DATE = DATE */,
    V_DATE_11      T_V_DATE /* T_V_DATE = DATE */,
    V_DATE_12      T_V_DATE /* T_V_DATE = DATE */,
    V_DATE_13      T_V_DATE /* T_V_DATE = DATE */,
    V_DATE_14      T_V_DATE /* T_V_DATE = DATE */,
    V_DATE_15      T_V_DATE /* T_V_DATE = DATE */,
    V_DATE_16      T_V_DATE /* T_V_DATE = DATE */,
    V_DATE_17      T_V_DATE /* T_V_DATE = DATE */,
    V_DATE_18      T_V_DATE /* T_V_DATE = DATE */,
    V_DATE_19      T_V_DATE /* T_V_DATE = DATE */,
    V_DATE_20      T_V_DATE /* T_V_DATE = DATE */,
    V_DATE_21      T_V_DATE /* T_V_DATE = DATE */,
    V_DATE_22      T_V_DATE /* T_V_DATE = DATE */,
    V_DATE_23      T_V_DATE /* T_V_DATE = DATE */,
    V_DATE_24      T_V_DATE /* T_V_DATE = DATE */,
    V_DATE_25      T_V_DATE /* T_V_DATE = DATE */,
    V_DATE_26      T_V_DATE /* T_V_DATE = DATE */,
    V_DATE_27      T_V_DATE /* T_V_DATE = DATE */,
    V_DATE_28      T_V_DATE /* T_V_DATE = DATE */,
    V_DATE_29      T_V_DATE /* T_V_DATE = DATE */,
    V_DATE_30      T_V_DATE /* T_V_DATE = DATE */,
    V_DATE_31      T_V_DATE /* T_V_DATE = DATE */,
    V_DATE_32      T_V_DATE /* T_V_DATE = DATE */,
    V_DATE_33      T_V_DATE /* T_V_DATE = DATE */,
    V_DATE_34      T_V_DATE /* T_V_DATE = DATE */,
    V_DATE_35      T_V_DATE /* T_V_DATE = DATE */,
    V_DATE_36      T_V_DATE /* T_V_DATE = DATE */,
    V_DATE_37      T_V_DATE /* T_V_DATE = DATE */,
    V_DATE_38      T_V_DATE /* T_V_DATE = DATE */,
    V_DATE_39      T_V_DATE /* T_V_DATE = DATE */,
    V_DATE_40      T_V_DATE /* T_V_DATE = DATE */,
    V_DATE_41      T_V_DATE /* T_V_DATE = DATE */,
    V_DATE_42      T_V_DATE /* T_V_DATE = DATE */,
    V_DATE_43      T_V_DATE /* T_V_DATE = DATE */,
    V_DATE_44      T_V_DATE /* T_V_DATE = DATE */,
    V_DATE_45      T_V_DATE /* T_V_DATE = DATE */,
    V_DATE_46      T_V_DATE /* T_V_DATE = DATE */,
    V_DATE_47      T_V_DATE /* T_V_DATE = DATE */,
    V_DATE_48      T_V_DATE /* T_V_DATE = DATE */,
    V_DATE_49      T_V_DATE /* T_V_DATE = DATE */,
    V_DATE_50      T_V_DATE /* T_V_DATE = DATE */,
    V_DATE_51      T_V_DATE /* T_V_DATE = DATE */,
    V_DATE_52      T_V_DATE /* T_V_DATE = DATE */,
    V_DATE_53      T_V_DATE /* T_V_DATE = DATE */,
    V_DATE_54      T_V_DATE /* T_V_DATE = DATE */,
    V_DATE_55      T_V_DATE /* T_V_DATE = DATE */,
    V_DATE_56      T_V_DATE /* T_V_DATE = DATE */,
    V_DATE_57      T_V_DATE /* T_V_DATE = DATE */,
    V_DATE_58      T_V_DATE /* T_V_DATE = DATE */,
    V_DATE_59      T_V_DATE /* T_V_DATE = DATE */,
    V_DATE_60      T_V_DATE /* T_V_DATE = DATE */,
    V_DATE_61      T_V_DATE /* T_V_DATE = DATE */,
    V_DATE_62      T_V_DATE /* T_V_DATE = DATE */,
    V_DATE_63      T_V_DATE /* T_V_DATE = DATE */,
    V_DATE_64      T_V_DATE /* T_V_DATE = DATE */,
    V_DATE_65      T_V_DATE /* T_V_DATE = DATE */,
    V_DATE_66      T_V_DATE /* T_V_DATE = DATE */,
    V_DATE_67      T_V_DATE /* T_V_DATE = DATE */,
    V_DATE_68      T_V_DATE /* T_V_DATE = DATE */,
    V_DATE_69      T_V_DATE /* T_V_DATE = DATE */,
    V_DATE_70      T_V_DATE /* T_V_DATE = DATE */,
    V_DATE_71      T_V_DATE /* T_V_DATE = DATE */,
    V_DATE_72      T_V_DATE /* T_V_DATE = DATE */,
    V_DATE_73      T_V_DATE /* T_V_DATE = DATE */,
    V_DATE_74      T_V_DATE /* T_V_DATE = DATE */,
    V_DATE_75      T_V_DATE /* T_V_DATE = DATE */,
    V_DATE_76      T_V_DATE /* T_V_DATE = DATE */,
    V_DATE_77      T_V_DATE /* T_V_DATE = DATE */,
    V_DATE_78      T_V_DATE /* T_V_DATE = DATE */,
    V_DATE_79      T_V_DATE /* T_V_DATE = DATE */,
    V_DATE_80      T_V_DATE /* T_V_DATE = DATE */,
    V_DATE_81      T_V_DATE /* T_V_DATE = DATE */,
    V_DATE_82      T_V_DATE /* T_V_DATE = DATE */,
    V_DATE_83      T_V_DATE /* T_V_DATE = DATE */,
    V_DATE_84      T_V_DATE /* T_V_DATE = DATE */,
    V_DATE_85      T_V_DATE /* T_V_DATE = DATE */,
    V_DATE_86      T_V_DATE /* T_V_DATE = DATE */,
    V_DATE_87      T_V_DATE /* T_V_DATE = DATE */,
    V_DATE_88      T_V_DATE /* T_V_DATE = DATE */,
    V_DATE_89      T_V_DATE /* T_V_DATE = DATE */,
    V_MONEY_00     T_V_MONEY /* T_V_MONEY = DECIMAL(18,2) */,
    V_MONEY_01     T_V_MONEY /* T_V_MONEY = DECIMAL(18,2) */,
    V_MONEY_02     T_V_MONEY /* T_V_MONEY = DECIMAL(18,2) */,
    V_MONEY_03     T_V_MONEY /* T_V_MONEY = DECIMAL(18,2) */,
    V_MONEY_04     T_V_MONEY /* T_V_MONEY = DECIMAL(18,2) */,
    V_MONEY_05     T_V_MONEY /* T_V_MONEY = DECIMAL(18,2) */,
    V_MONEY_06     T_V_MONEY /* T_V_MONEY = DECIMAL(18,2) */,
    V_MONEY_07     T_V_MONEY /* T_V_MONEY = DECIMAL(18,2) */,
    V_MONEY_08     T_V_MONEY /* T_V_MONEY = DECIMAL(18,2) */,
    V_MONEY_09     T_V_MONEY /* T_V_MONEY = DECIMAL(18,2) */,
    V_MONEY_10     T_V_MONEY /* T_V_MONEY = DECIMAL(18,2) */,
    V_MONEY_11     T_V_MONEY /* T_V_MONEY = DECIMAL(18,2) */,
    V_MONEY_12     T_V_MONEY /* T_V_MONEY = DECIMAL(18,2) */,
    V_MONEY_13     T_V_MONEY /* T_V_MONEY = DECIMAL(18,2) */,
    V_MONEY_14     T_V_MONEY /* T_V_MONEY = DECIMAL(18,2) */,
    V_MONEY_15     T_V_MONEY /* T_V_MONEY = DECIMAL(18,2) */,
    V_MONEY_16     T_V_MONEY /* T_V_MONEY = DECIMAL(18,2) */,
    V_MONEY_17     T_V_MONEY /* T_V_MONEY = DECIMAL(18,2) */,
    V_MONEY_18     T_V_MONEY /* T_V_MONEY = DECIMAL(18,2) */,
    V_MONEY_19     T_V_MONEY /* T_V_MONEY = DECIMAL(18,2) */,
    V_MONEY_20     T_V_MONEY /* T_V_MONEY = DECIMAL(18,2) */,
    V_MONEY_21     T_V_MONEY /* T_V_MONEY = DECIMAL(18,2) */,
    V_MONEY_22     T_V_MONEY /* T_V_MONEY = DECIMAL(18,2) */,
    V_MONEY_23     T_V_MONEY /* T_V_MONEY = DECIMAL(18,2) */,
    V_MONEY_24     T_V_MONEY /* T_V_MONEY = DECIMAL(18,2) */,
    V_MONEY_25     T_V_MONEY /* T_V_MONEY = DECIMAL(18,2) */,
    V_MONEY_26     T_V_MONEY /* T_V_MONEY = DECIMAL(18,2) */,
    V_MONEY_27     T_V_MONEY /* T_V_MONEY = DECIMAL(18,2) */,
    V_MONEY_28     T_V_MONEY /* T_V_MONEY = DECIMAL(18,2) */,
    V_MONEY_29     T_V_MONEY /* T_V_MONEY = DECIMAL(18,2) */,
    V_MONEY_30     T_V_MONEY /* T_V_MONEY = DECIMAL(18,2) */,
    V_MONEY_31     T_V_MONEY /* T_V_MONEY = DECIMAL(18,2) */,
    V_MONEY_32     T_V_MONEY /* T_V_MONEY = DECIMAL(18,2) */,
    V_MONEY_33     T_V_MONEY /* T_V_MONEY = DECIMAL(18,2) */,
    V_MONEY_34     T_V_MONEY /* T_V_MONEY = DECIMAL(18,2) */,
    V_MONEY_35     T_V_MONEY /* T_V_MONEY = DECIMAL(18,2) */,
    V_MONEY_36     T_V_MONEY /* T_V_MONEY = DECIMAL(18,2) */,
    V_MONEY_37     T_V_MONEY /* T_V_MONEY = DECIMAL(18,2) */,
    V_MONEY_38     T_V_MONEY /* T_V_MONEY = DECIMAL(18,2) */,
    V_MONEY_39     T_V_MONEY /* T_V_MONEY = DECIMAL(18,2) */,
    V_MONEY_40     T_V_MONEY /* T_V_MONEY = DECIMAL(18,2) */,
    V_MONEY_41     T_V_MONEY /* T_V_MONEY = DECIMAL(18,2) */,
    V_MONEY_42     T_V_MONEY /* T_V_MONEY = DECIMAL(18,2) */,
    V_MONEY_43     T_V_MONEY /* T_V_MONEY = DECIMAL(18,2) */,
    V_MONEY_44     T_V_MONEY /* T_V_MONEY = DECIMAL(18,2) */,
    V_MONEY_45     T_V_MONEY /* T_V_MONEY = DECIMAL(18,2) */,
    V_MONEY_46     T_V_MONEY /* T_V_MONEY = DECIMAL(18,2) */,
    V_MONEY_47     T_V_MONEY /* T_V_MONEY = DECIMAL(18,2) */,
    V_MONEY_48     T_V_MONEY /* T_V_MONEY = DECIMAL(18,2) */,
    V_MONEY_49     T_V_MONEY /* T_V_MONEY = DECIMAL(18,2) */,
    V_MONEY_50     T_V_MONEY /* T_V_MONEY = DECIMAL(18,2) */,
    V_MONEY_51     T_V_MONEY /* T_V_MONEY = DECIMAL(18,2) */,
    V_MONEY_52     T_V_MONEY /* T_V_MONEY = DECIMAL(18,2) */,
    V_MONEY_53     T_V_MONEY /* T_V_MONEY = DECIMAL(18,2) */,
    V_MONEY_54     T_V_MONEY /* T_V_MONEY = DECIMAL(18,2) */,
    V_MONEY_55     T_V_MONEY /* T_V_MONEY = DECIMAL(18,2) */,
    V_MONEY_56     T_V_MONEY /* T_V_MONEY = DECIMAL(18,2) */,
    V_MONEY_57     T_V_MONEY /* T_V_MONEY = DECIMAL(18,2) */,
    V_MONEY_58     T_V_MONEY /* T_V_MONEY = DECIMAL(18,2) */,
    V_MONEY_59     T_V_MONEY /* T_V_MONEY = DECIMAL(18,2) */,
    V_MONEY_60     T_V_MONEY /* T_V_MONEY = DECIMAL(18,2) */,
    V_MONEY_61     T_V_MONEY /* T_V_MONEY = DECIMAL(18,2) */,
    V_MONEY_62     T_V_MONEY /* T_V_MONEY = DECIMAL(18,2) */,
    V_MONEY_63     T_V_MONEY /* T_V_MONEY = DECIMAL(18,2) */,
    V_MONEY_64     T_V_MONEY /* T_V_MONEY = DECIMAL(18,2) */,
    V_MONEY_65     T_V_MONEY /* T_V_MONEY = DECIMAL(18,2) */,
    V_MONEY_66     T_V_MONEY /* T_V_MONEY = DECIMAL(18,2) */,
    V_MONEY_67     T_V_MONEY /* T_V_MONEY = DECIMAL(18,2) */,
    V_MONEY_68     T_V_MONEY /* T_V_MONEY = DECIMAL(18,2) */,
    V_MONEY_69     T_V_MONEY /* T_V_MONEY = DECIMAL(18,2) */,
    V_MONEY_70     T_V_MONEY /* T_V_MONEY = DECIMAL(18,2) */,
    V_MONEY_71     T_V_MONEY /* T_V_MONEY = DECIMAL(18,2) */,
    V_MONEY_72     T_V_MONEY /* T_V_MONEY = DECIMAL(18,2) */,
    V_MONEY_73     T_V_MONEY /* T_V_MONEY = DECIMAL(18,2) */,
    V_MONEY_74     T_V_MONEY /* T_V_MONEY = DECIMAL(18,2) */,
    V_MONEY_75     T_V_MONEY /* T_V_MONEY = DECIMAL(18,2) */,
    V_MONEY_76     T_V_MONEY /* T_V_MONEY = DECIMAL(18,2) */,
    V_MONEY_77     T_V_MONEY /* T_V_MONEY = DECIMAL(18,2) */,
    V_MONEY_78     T_V_MONEY /* T_V_MONEY = DECIMAL(18,2) */,
    V_MONEY_79     T_V_MONEY /* T_V_MONEY = DECIMAL(18,2) */,
    V_MONEY_80     T_V_MONEY /* T_V_MONEY = DECIMAL(18,2) */,
    V_MONEY_81     T_V_MONEY /* T_V_MONEY = DECIMAL(18,2) */,
    V_MONEY_82     T_V_MONEY /* T_V_MONEY = DECIMAL(18,2) */,
    V_MONEY_83     T_V_MONEY /* T_V_MONEY = DECIMAL(18,2) */,
    V_MONEY_84     T_V_MONEY /* T_V_MONEY = DECIMAL(18,2) */,
    V_MONEY_85     T_V_MONEY /* T_V_MONEY = DECIMAL(18,2) */,
    V_MONEY_86     T_V_MONEY /* T_V_MONEY = DECIMAL(18,2) */,
    V_MONEY_87     T_V_MONEY /* T_V_MONEY = DECIMAL(18,2) */,
    V_MONEY_88     T_V_MONEY /* T_V_MONEY = DECIMAL(18,2) */,
    V_MONEY_89     T_V_MONEY /* T_V_MONEY = DECIMAL(18,2) */,
    V_REAL_00      T_V_REAL /* T_V_REAL = DOUBLE PRECISION */,
    V_REAL_01      T_V_REAL /* T_V_REAL = DOUBLE PRECISION */,
    V_REAL_02      T_V_REAL /* T_V_REAL = DOUBLE PRECISION */,
    V_REAL_03      T_V_REAL /* T_V_REAL = DOUBLE PRECISION */,
    V_REAL_04      T_V_REAL /* T_V_REAL = DOUBLE PRECISION */,
    V_REAL_05      T_V_REAL /* T_V_REAL = DOUBLE PRECISION */,
    V_REAL_06      T_V_REAL /* T_V_REAL = DOUBLE PRECISION */,
    V_REAL_07      T_V_REAL /* T_V_REAL = DOUBLE PRECISION */,
    V_REAL_08      T_V_REAL /* T_V_REAL = DOUBLE PRECISION */,
    V_REAL_09      T_V_REAL /* T_V_REAL = DOUBLE PRECISION */,
    V_REAL_10      T_V_REAL /* T_V_REAL = DOUBLE PRECISION */,
    V_REAL_11      T_V_REAL /* T_V_REAL = DOUBLE PRECISION */,
    V_REAL_12      T_V_REAL /* T_V_REAL = DOUBLE PRECISION */,
    V_REAL_13      T_V_REAL /* T_V_REAL = DOUBLE PRECISION */,
    V_REAL_14      T_V_REAL /* T_V_REAL = DOUBLE PRECISION */,
    V_REAL_15      T_V_REAL /* T_V_REAL = DOUBLE PRECISION */,
    V_REAL_16      T_V_REAL /* T_V_REAL = DOUBLE PRECISION */,
    V_REAL_17      T_V_REAL /* T_V_REAL = DOUBLE PRECISION */,
    V_REAL_18      T_V_REAL /* T_V_REAL = DOUBLE PRECISION */,
    V_REAL_19      T_V_REAL /* T_V_REAL = DOUBLE PRECISION */,
    V_REAL_20      T_V_REAL /* T_V_REAL = DOUBLE PRECISION */,
    V_REAL_21      T_V_REAL /* T_V_REAL = DOUBLE PRECISION */,
    V_REAL_22      T_V_REAL /* T_V_REAL = DOUBLE PRECISION */,
    V_REAL_23      T_V_REAL /* T_V_REAL = DOUBLE PRECISION */,
    V_REAL_24      T_V_REAL /* T_V_REAL = DOUBLE PRECISION */,
    V_REAL_25      T_V_REAL /* T_V_REAL = DOUBLE PRECISION */,
    V_REAL_26      T_V_REAL /* T_V_REAL = DOUBLE PRECISION */,
    V_REAL_27      T_V_REAL /* T_V_REAL = DOUBLE PRECISION */,
    V_REAL_28      T_V_REAL /* T_V_REAL = DOUBLE PRECISION */,
    V_REAL_29      T_V_REAL /* T_V_REAL = DOUBLE PRECISION */,
    V_REAL_30      T_V_REAL /* T_V_REAL = DOUBLE PRECISION */,
    V_REAL_31      T_V_REAL /* T_V_REAL = DOUBLE PRECISION */,
    V_REAL_32      T_V_REAL /* T_V_REAL = DOUBLE PRECISION */,
    V_REAL_33      T_V_REAL /* T_V_REAL = DOUBLE PRECISION */,
    V_REAL_34      T_V_REAL /* T_V_REAL = DOUBLE PRECISION */,
    V_REAL_35      T_V_REAL /* T_V_REAL = DOUBLE PRECISION */,
    V_REAL_36      T_V_REAL /* T_V_REAL = DOUBLE PRECISION */,
    V_REAL_37      T_V_REAL /* T_V_REAL = DOUBLE PRECISION */,
    V_REAL_38      T_V_REAL /* T_V_REAL = DOUBLE PRECISION */,
    V_REAL_39      T_V_REAL /* T_V_REAL = DOUBLE PRECISION */,
    V_REAL_40      T_V_REAL /* T_V_REAL = DOUBLE PRECISION */,
    V_REAL_41      T_V_REAL /* T_V_REAL = DOUBLE PRECISION */,
    V_REAL_42      T_V_REAL /* T_V_REAL = DOUBLE PRECISION */,
    V_REAL_43      T_V_REAL /* T_V_REAL = DOUBLE PRECISION */,
    V_REAL_44      T_V_REAL /* T_V_REAL = DOUBLE PRECISION */,
    V_REAL_45      T_V_REAL /* T_V_REAL = DOUBLE PRECISION */,
    V_REAL_46      T_V_REAL /* T_V_REAL = DOUBLE PRECISION */,
    V_REAL_47      T_V_REAL /* T_V_REAL = DOUBLE PRECISION */,
    V_REAL_48      T_V_REAL /* T_V_REAL = DOUBLE PRECISION */,
    V_REAL_49      T_V_REAL /* T_V_REAL = DOUBLE PRECISION */,
    V_REAL_50      T_V_REAL /* T_V_REAL = DOUBLE PRECISION */,
    V_REAL_51      T_V_REAL /* T_V_REAL = DOUBLE PRECISION */,
    V_REAL_52      T_V_REAL /* T_V_REAL = DOUBLE PRECISION */,
    V_REAL_53      T_V_REAL /* T_V_REAL = DOUBLE PRECISION */,
    V_REAL_54      T_V_REAL /* T_V_REAL = DOUBLE PRECISION */,
    V_REAL_55      T_V_REAL /* T_V_REAL = DOUBLE PRECISION */,
    V_REAL_56      T_V_REAL /* T_V_REAL = DOUBLE PRECISION */,
    V_REAL_57      T_V_REAL /* T_V_REAL = DOUBLE PRECISION */,
    V_REAL_58      T_V_REAL /* T_V_REAL = DOUBLE PRECISION */,
    V_REAL_59      T_V_REAL /* T_V_REAL = DOUBLE PRECISION */,
    V_REAL_60      T_V_REAL /* T_V_REAL = DOUBLE PRECISION */,
    V_REAL_61      T_V_REAL /* T_V_REAL = DOUBLE PRECISION */,
    V_REAL_62      T_V_REAL /* T_V_REAL = DOUBLE PRECISION */,
    V_REAL_63      T_V_REAL /* T_V_REAL = DOUBLE PRECISION */,
    V_REAL_64      T_V_REAL /* T_V_REAL = DOUBLE PRECISION */,
    V_REAL_65      T_V_REAL /* T_V_REAL = DOUBLE PRECISION */,
    V_REAL_66      T_V_REAL /* T_V_REAL = DOUBLE PRECISION */,
    V_REAL_67      T_V_REAL /* T_V_REAL = DOUBLE PRECISION */,
    V_REAL_68      T_V_REAL /* T_V_REAL = DOUBLE PRECISION */,
    V_REAL_69      T_V_REAL /* T_V_REAL = DOUBLE PRECISION */,
    V_REAL_70      T_V_REAL /* T_V_REAL = DOUBLE PRECISION */,
    V_REAL_71      T_V_REAL /* T_V_REAL = DOUBLE PRECISION */,
    V_REAL_72      T_V_REAL /* T_V_REAL = DOUBLE PRECISION */,
    V_REAL_73      T_V_REAL /* T_V_REAL = DOUBLE PRECISION */,
    V_REAL_74      T_V_REAL /* T_V_REAL = DOUBLE PRECISION */,
    V_REAL_75      T_V_REAL /* T_V_REAL = DOUBLE PRECISION */,
    V_REAL_76      T_V_REAL /* T_V_REAL = DOUBLE PRECISION */,
    V_REAL_77      T_V_REAL /* T_V_REAL = DOUBLE PRECISION */,
    V_REAL_78      T_V_REAL /* T_V_REAL = DOUBLE PRECISION */,
    V_REAL_79      T_V_REAL /* T_V_REAL = DOUBLE PRECISION */,
    V_REAL_80      T_V_REAL /* T_V_REAL = DOUBLE PRECISION */,
    V_REAL_81      T_V_REAL /* T_V_REAL = DOUBLE PRECISION */,
    V_REAL_82      T_V_REAL /* T_V_REAL = DOUBLE PRECISION */,
    V_REAL_83      T_V_REAL /* T_V_REAL = DOUBLE PRECISION */,
    V_REAL_84      T_V_REAL /* T_V_REAL = DOUBLE PRECISION */,
    V_REAL_85      T_V_REAL /* T_V_REAL = DOUBLE PRECISION */,
    V_REAL_86      T_V_REAL /* T_V_REAL = DOUBLE PRECISION */,
    V_REAL_87      T_V_REAL /* T_V_REAL = DOUBLE PRECISION */,
    V_REAL_88      T_V_REAL /* T_V_REAL = DOUBLE PRECISION */,
    V_REAL_89      T_V_REAL /* T_V_REAL = DOUBLE PRECISION */,
    V_BOOLEAN_00   T_V_BOOLEAN /* T_V_BOOLEAN = INTEGER CHECK (VALUE IN(0, 1) OR VALUE IS NULL) */,
    V_BOOLEAN_01   T_V_BOOLEAN /* T_V_BOOLEAN = INTEGER CHECK (VALUE IN(0, 1) OR VALUE IS NULL) */,
    V_BOOLEAN_02   T_V_BOOLEAN /* T_V_BOOLEAN = INTEGER CHECK (VALUE IN(0, 1) OR VALUE IS NULL) */,
    V_BOOLEAN_03   T_V_BOOLEAN /* T_V_BOOLEAN = INTEGER CHECK (VALUE IN(0, 1) OR VALUE IS NULL) */,
    V_BOOLEAN_04   T_V_BOOLEAN /* T_V_BOOLEAN = INTEGER CHECK (VALUE IN(0, 1) OR VALUE IS NULL) */,
    V_BOOLEAN_05   T_V_BOOLEAN /* T_V_BOOLEAN = INTEGER CHECK (VALUE IN(0, 1) OR VALUE IS NULL) */,
    V_BOOLEAN_06   T_V_BOOLEAN /* T_V_BOOLEAN = INTEGER CHECK (VALUE IN(0, 1) OR VALUE IS NULL) */,
    V_BOOLEAN_07   T_V_BOOLEAN /* T_V_BOOLEAN = INTEGER CHECK (VALUE IN(0, 1) OR VALUE IS NULL) */,
    V_BOOLEAN_08   T_V_BOOLEAN /* T_V_BOOLEAN = INTEGER CHECK (VALUE IN(0, 1) OR VALUE IS NULL) */,
    V_BOOLEAN_09   T_V_BOOLEAN /* T_V_BOOLEAN = INTEGER CHECK (VALUE IN(0, 1) OR VALUE IS NULL) */,
    V_BOOLEAN_10   T_V_BOOLEAN /* T_V_BOOLEAN = INTEGER CHECK (VALUE IN(0, 1) OR VALUE IS NULL) */,
    V_BOOLEAN_11   T_V_BOOLEAN /* T_V_BOOLEAN = INTEGER CHECK (VALUE IN(0, 1) OR VALUE IS NULL) */,
    V_BOOLEAN_12   T_V_BOOLEAN /* T_V_BOOLEAN = INTEGER CHECK (VALUE IN(0, 1) OR VALUE IS NULL) */,
    V_BOOLEAN_13   T_V_BOOLEAN /* T_V_BOOLEAN = INTEGER CHECK (VALUE IN(0, 1) OR VALUE IS NULL) */,
    V_BOOLEAN_14   T_V_BOOLEAN /* T_V_BOOLEAN = INTEGER CHECK (VALUE IN(0, 1) OR VALUE IS NULL) */,
    V_BOOLEAN_15   T_V_BOOLEAN /* T_V_BOOLEAN = INTEGER CHECK (VALUE IN(0, 1) OR VALUE IS NULL) */,
    V_BOOLEAN_16   T_V_BOOLEAN /* T_V_BOOLEAN = INTEGER CHECK (VALUE IN(0, 1) OR VALUE IS NULL) */,
    V_BOOLEAN_17   T_V_BOOLEAN /* T_V_BOOLEAN = INTEGER CHECK (VALUE IN(0, 1) OR VALUE IS NULL) */,
    V_BOOLEAN_18   T_V_BOOLEAN /* T_V_BOOLEAN = INTEGER CHECK (VALUE IN(0, 1) OR VALUE IS NULL) */,
    V_BOOLEAN_19   T_V_BOOLEAN /* T_V_BOOLEAN = INTEGER CHECK (VALUE IN(0, 1) OR VALUE IS NULL) */,
    V_MOMENT_00    T_V_MOMENT /* T_V_MOMENT = TIMESTAMP */,
    V_MOMENT_01    T_V_MOMENT /* T_V_MOMENT = TIMESTAMP */,
    V_MOMENT_02    T_V_MOMENT /* T_V_MOMENT = TIMESTAMP */,
    V_MOMENT_03    T_V_MOMENT /* T_V_MOMENT = TIMESTAMP */,
    V_MOMENT_04    T_V_MOMENT /* T_V_MOMENT = TIMESTAMP */,
    V_MOMENT_05    T_V_MOMENT /* T_V_MOMENT = TIMESTAMP */,
    V_MOMENT_06    T_V_MOMENT /* T_V_MOMENT = TIMESTAMP */,
    V_MOMENT_07    T_V_MOMENT /* T_V_MOMENT = TIMESTAMP */,
    V_MOMENT_08    T_V_MOMENT /* T_V_MOMENT = TIMESTAMP */,
    V_MOMENT_09    T_V_MOMENT /* T_V_MOMENT = TIMESTAMP */,
    V_MOMENT_10    T_V_MOMENT /* T_V_MOMENT = TIMESTAMP */,
    V_MOMENT_11    T_V_MOMENT /* T_V_MOMENT = TIMESTAMP */,
    V_MOMENT_12    T_V_MOMENT /* T_V_MOMENT = TIMESTAMP */,
    V_MOMENT_13    T_V_MOMENT /* T_V_MOMENT = TIMESTAMP */,
    V_MOMENT_14    T_V_MOMENT /* T_V_MOMENT = TIMESTAMP */,
    V_MOMENT_15    T_V_MOMENT /* T_V_MOMENT = TIMESTAMP */,
    V_MOMENT_16    T_V_MOMENT /* T_V_MOMENT = TIMESTAMP */,
    V_MOMENT_17    T_V_MOMENT /* T_V_MOMENT = TIMESTAMP */,
    V_MOMENT_18    T_V_MOMENT /* T_V_MOMENT = TIMESTAMP */,
    V_MOMENT_19    T_V_MOMENT /* T_V_MOMENT = TIMESTAMP */,
    V_USERS_00     T_ID /* T_ID = INTEGER */,
    V_USERS_01     T_ID /* T_ID = INTEGER */,
    V_USERS_02     T_ID /* T_ID = INTEGER */,
    V_USERS_03     T_ID /* T_ID = INTEGER */,
    V_MONTH_00     T_V_MONTH /* T_V_MONTH = INTEGER CHECK(value between 1 and 12) */,
    V_MONTH_01     T_V_MONTH /* T_V_MONTH = INTEGER CHECK(value between 1 and 12) */,
    V_MONTH_02     T_V_MONTH /* T_V_MONTH = INTEGER CHECK(value between 1 and 12) */,
    V_MONTH_03     T_V_MONTH /* T_V_MONTH = INTEGER CHECK(value between 1 and 12) */
);




... не надо было открывать, я ведь предупреждал.
Блобы тоже есть, но в виде отдельной таблички Attachment, у каждой записи виртуальной таблички может быть от нуля до скольки угодно блобов разного назначения.
...
Ну так вот, "настоящие" FK там есть, но только к одной, настоящей табличке USERS. А между "логическими" (виртуальными?) табличками связи реализованы с помощью промежуточной табличке LINK:
Тут уже безопасно
Код: sql
1.
2.
3.
4.
5.
CREATE TABLE LINK (
    TUPLE_ID         T_TUPLE_ID NOT NULL /* T_TUPLE_ID = INTEGER */,
    ASSOCIATION_ID   T_ASSOCIATION_ID NOT NULL /* T_ASSOCIATION_ID = INTEGER */,
    LINKED_TUPLE_ID  T_TUPLE_ID NOT NULL /* T_TUPLE_ID = INTEGER */
);



А уж у этой таблички - настоящие FK к элементам виртуальных сущностей.

Как ни странно, до сих пор работает. Но нагрузки не очень великие: самое большее - около сотни одновременно работающих пользователей и базы невелики, а в базах основной объем - небольшие блобы (образы электронных документов). Ну и клиент старательно пишем так, чтобы там, где большие объемы - грузить поменьше.
Когда-то сделали для одного заказчика, тупо "давай-давай побыстрее", а оно все живет и живет, хотя и заказчика того уже нет. Все обросло скриптами, отчетниками, плагинами и переделывать вряд ли кто-то будет.
...
Триггеры используются, но не для контроля целостности, а для всякой фигни. Например, для генерации значения первичного ключа или проверки вводимого имени на соответствие шаблону и т.п. Или эвенты рассылать.
...
FB 2.0. :)
...
Рейтинг: 0 / 0
Что лучше: FK или триггеры проверки целостности?
    #39633885
m7m
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ariochненужная зависимость разных сущностей между собой - больше надо помнить и учитывать, а гибкость меньше
О какой зависимости то речь, нет никакой зависимости, ну я по крайней мере не вижу её, как не вижу ни больше, ни меньше гибкости
Ariochm7mтолько для тех кто в общем справочнике

в добавок еще ненужное усложнение системы

для одних объектов мы берем нoвые ID одним методом из одного хранилища, а для других - другим методом из других хранилищ. Это нужно всегда помнить и нигде не перепутать, вмеcто унификации кода.
О чем речь, где тут усложнения, объекты, хранилища?
о каких методах то речь, gen_id(...) что-ли
что тут помнить и путать, триггер на вставку new.id=gen_id(...) не на ту таблицу навесить, генератор попутать
AriochА если потом какой-то изначально отдельный объект захочется внести в справочник?
тут я совсем не понимаю :(
...
Рейтинг: 0 / 0
Что лучше: FK или триггеры проверки целостности?
    #39633896
fraks
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Читайте классику :)

Анатолий Тенцер. База данных - хранилище объектов.
Компьютер пресс, 2001 год.

https://compress.ru/article.aspx?id=11515

Для тех кто не в курсе. Это не теоретические изыскания и эксперименты. Из
того в те же годы была создана система автоматизации крупной оптовой фирмы по торговле медпрепаратами.
Автоматизировано все, включая бухгалтерию.
В стратье приведено на примере Interbase или Firebird но реальная система работала на MS SQL.
...
Рейтинг: 0 / 0
Что лучше: FK или триггеры проверки целостности?
    #39633904
Котовасия
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fraksЧитайте классику :)

Анатолий Тенцер. База данных - хранилище объектов.
Компьютер пресс, 2001 год.

https://compress.ru/article.aspx?id=11515

Для тех кто не в курсе. Это не теоретические изыскания и эксперименты. Из
того в те же годы была создана система автоматизации крупной оптовой фирмы по торговле медпрепаратами.
Автоматизировано все, включая бухгалтерию.
В стратье приведено на примере Interbase или Firebird но реальная система работала на MS SQL.
Так ничего хорошего же, в статье все недостатки и разжеваны.
Вместо прямого использования возможностей СУБД - костыльная эмуляция этих возможностей, с длительным нетрадиционным послесексом в процессе сопровождения.
...
Рейтинг: 0 / 0
Что лучше: FK или триггеры проверки целостности?
    #39633916
Фотография Док
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
какой пятничный топик :)

зы. все нубы проходят через эту стадию познания
...
Рейтинг: 0 / 0
Что лучше: FK или триггеры проверки целостности?
    #39633974
Гаджимурадов Рустам
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Котовасия, спасибо, это уже поинтереснее.

Котовасия> ... не надо было открывать, я ведь предупреждал.

Да уж, название таблицы вполне "говорящее". :)
А почему 89 (а не 99) и почему полей разных типов количество?
Собственный слой метаданных в БД не создавали, всё в клиенте?

А между "логическими" (виртуальными?) табличками связи
реализованы с помощью промежуточной табличке LINK:

CREATE TABLE LINK (
TUPLE_ID T_TUPLE_ID NOT NULL /* T_TUPLE_ID = INTEGER */,
ASSOCIATION_ID T_ASSOCIATION_ID NOT NULL /* T_ASSOCIATION_ID = INTEGER */,
LINKED_TUPLE_ID T_TUPLE_ID NOT NULL /* T_TUPLE_ID = INTEGER */

А уж у этой таблички - настоящие FK к элементам виртуальных сущностей.
Что здесь ASSOCIATION_ID и что LINKED_TUPLE_ID ?
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Что лучше: FK или триггеры проверки целостности?
    #39634002
Котовасия
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Гаджимурадов Рустам>Да уж, название таблицы вполне "говорящее". :)
Ты не представляешь, как тяжело придумать название генерируемого бреда...

Гаджимурадов Рустам> А почему 89 (а не 99) и почему полей разных типов количество?
Со временем проснулась жаба и задушила...
...
Метаданные в базе, да.
Табличка Collection - описывает сущность ("виртуальную" табличку). Включает название, и некоторые доп. признаки: "может иметь аттачменты" (блобы), описание доп. признаков (в json-структуре - хранится в блобе) и еще по мелочи.
Табличка Attr_Def - описывает атрибуты сущностей. Т.е., "поля". Включает ссылку на элемент collection, название физического поля таблички tuple, тип атрибута, логическое имя, хинт (именно хинт - то, что всплывает при наведении мышкой на заголовок поля таблички), значения по умолчанию, и проч.
Табличка Association. Описывает связь между логическими сущностями. Аналог FK. Включает ссылки на элементы collection, поведение при удалении, логическое имя, ссылки на пару других ассоциаций (тринзитивные и кардинальные зависимости) и т.п.

Гаджимурадов Рустам> Что здесь ASSOCIATION_ID и что LINKED_TUPLE_ID ?
association_id - указывает, какую связь между сущностями реализует.
tuple_id - id мастер-записи,
linked_tuple_id - id FK-записи.
~~~~~~~~
Еще куча всякостей для оргаганизации групп прав юзеров, для организации псевдофайловой ("дерево", если коротко) структуры некоторых сущностей, обвязка для работы с отчетами, хранилище плагинов и еще разная ерундень.
...
Поначалу даже сделали "наследуемые" (как в постгре) сущности, но так как за года использования ни разу не понадобилось, потихоньку выпилили, тем более что сия фича требовали нехилых усилий при доработке и из-за ненужности дико бесила.
...
Рейтинг: 0 / 0
Что лучше: FK или триггеры проверки целостности?
    #39634010
Котовасия
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Если кто-то хочет повторить сей подвиг: лучше не надо. Столько секаса ради призрачного преимущества менять метаданные "на лету". Да и не преимущество это вовсе. Один черт во многих случаях "на лету" не получается. Например, в шаблонах отчета (FR) - вот, не стало поля - и? Какая разница, логическое поле или физическое, ведь скрипт создания отчета сам собой не поменяется.

А еще потом выясняется, что систему хотят развернуть под нагрузкой, в 20-ть превышающей запланированную, а ты бекаешь и мекаешь по поводу невозможности создания индексов на виртуальных полях.
...
Все метаданные в базе есть. Ничто не мешает их дополнить своими в соответствии с пожеланиями левой пятки.
...
Рейтинг: 0 / 0
Что лучше: FK или триггеры проверки целостности?
    #39634079
Гаджимурадов Рустам
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Котовасия> А почему 89 (а не 99) и почему полей разных типов количество?

Со временем проснулась жаба и задушила... А что, реально бывало 89 однородных атрибутов? Да ещё в универсальный справочник?
Я вообще больше 20 с ходу не припомню, да и те - в универсальный нельзя объединять.

Котовасия> Что здесь ASSOCIATION_ID и что LINKED_TUPLE_ID ?

association_id - указывает, какую связь между сущностями реализует.
linked_tuple_id - id FK-записи.Всё равно не понял. В чём суть/назначение первого поля, и на чот ссылается второе поле? Можно примером.

КотовасияМетаданные в базе, да.
Табличка Collection - описывает сущность ("виртуальную" табличку). Включает название, и некоторые доп. признаки: "может иметь аттачменты" (блобы), описание доп. признаков (в json-структуре - хранится в блобе) и еще по мелочи.
Табличка Attr_Def - описывает атрибуты сущностей. Т.е., "поля". Включает ссылку на элемент collection, название физического поля таблички tuple, тип атрибута, логическое имя, хинт (именно хинт - то, что всплывает при наведении мышкой на заголовок поля таблички), значения по умолчанию, и проч.
Табличка Association. Описывает связь между логическими сущностями. Аналог FK. Включает ссылки на элементы collection, поведение при удалении, логическое имя, ссылки на пару других ассоциаций (тринзитивные и кардинальные зависимости) и т.п.

~~~~~~~~
Еще куча всякостей для оргаганизации групп прав юзеров, для организации псевдофайловой ("дерево", если коротко) структуры некоторых сущностей, обвязка для работы с отчетами, хранилище плагинов и еще разная ерундень.
...
Поначалу даже сделали "наследуемые" (как в постгре) сущности, но так как за года использования ни разу не понадобилось, потихоньку выпилили, тем более что сия фича требовали нехилых усилий при доработке и из-за ненужности дико бесила.

Если есть время и желание - опиши, пожалуйста, поподробнее, лучше отдельным топиком
(можно тут, можно в разделах Delphi или РИС/Проектирование), очень интересно почитать.

КотовасияСтолько секаса ради призрачного преимущества менять метаданные "на лету". Да и не преимущество это вовсе. Один черт во многих случаях "на лету" не получается.Так точно. Правда, делается это не только/столько ради "на лету", сколько ради каких-то
фич, "автогенераций", наследуемых форм и т.д. С другой стороны, всё (или почти всё) это
можно и на основе родных метаданных делать (наверное), но обычно решают лепить не
костыль, а собственный лисапед.

КотовасияВсе метаданные в базе есть. Ничто не мешает их дополнить своими в соответствии с пожеланиями левой пятки.Дык доп.метаданные как раз и станут "своим" слоем, рядышком или "сверху".
...
Рейтинг: 0 / 0
Что лучше: FK или триггеры проверки целостности?
    #39634080
Гаджимурадов Рустам
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Гаджимурадов РустамКотовасияМетаданные в базе, да.
Если есть время и желание - опиши, пожалуйста, поподробнее, лучше отдельным топиком
(можно тут, можно в разделах Delphi или РИС/Проектирование), очень интересно почитать.Или ссылку дай, если где-то уже описывал (хотя я ничего подобного
не припомню за последние годы от тебя, разве что очень давно).
...
Рейтинг: 0 / 0
Что лучше: FK или триггеры проверки целостности?
    #39634269
V.Borzov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Старый плюшевый мишка
Вооот. А теперь представим себе мастер-таблицу, скажем, статусов документов. Нуусс, скажем, счетов.

Новый
В работе
Оплачен
Отгружено
Закрыт

И таблицу этих самых счетов. Из пары мильёнчиков документов хотя бы. FK от которой по статусу кивает на эту мастер-таблицу. Которая никогда и никем редактироваться не будет. И запросы с условием на статус в where. Которые подхватят этот самый индекс. Особенно ищущие закрытые, лет эдак через 10 функлицирования предприятия. И прикинем сизифовы усилия сервера на регулярном ресторе этой базы при создании этого самого индекса.

Жил один еврей, так он сказал, что всё относительно. Как говорят highly likely - it depends. Сдаёццо мне, что слова умного человека вырваны из контекста. Хотя в общем случае, безусловно, FK рулит.

Да, понял, спасибо. Теперь мне очевидно, что я те слова его неправильно понял, действительно вырвал из контекста.
...
Рейтинг: 0 / 0
Что лучше: FK или триггеры проверки целостности?
    #39634355
Котовасия
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Гаджимурадов Рустам>А что, реально бывало 89 однородных атрибутов? Да ещё в универсальный справочник?
Гаджимурадов Рустам>Я вообще больше 20 с ходу не припомню, да и те - в универсальный нельзя объединять.
У нас один активный товарищ все поля тестовыми сделал, ровно сто. И позвонил нам, когда сто первое попытался добавить.
Справочник назывался То ли "План чего-то", то ли "Подготовительная записка". Он туда вбахал фамилии руководства, подрядчика, генподрядчика, заказчика, гензаказчика, ответственных за то-сё, названия этого самого того-сего, даты начала-окончания-завершения чего-то, с кем согласовано и кем утверждено, сколько стоит и сколько стоило раньше и почему теперь так дорого, адреса "вертолетных площадок"(???), номера телефонов, номера и даты договоров, с пяток полей "Примечание 1", "ПРимечание 2"...
...
Гаджимурадов Рустам>ASSOCIATION, LINK...?
И так, у нас есть таблички:
COLLECTION - описания этих самых сущностей.
ATTR_DEF - список описаний атрибутов сущностей.
ASSOCIATION - описание связей между сущностями (как бы FK).

TUPLE - тут все в куче, экземпляры сущностей (виртуальных табличек).
LINK - экземпляры связей между сущностями.

Пример. Сущности ("таблички"): Улица, Район города, Город.
В табличке COLLECTION
idНаименование1 Улица2 Район3 Город

В табличке ATTR_DEF:
id id коллекции Наименование Тип Имя физического поля1 1 Наименование Строка v_str_002 1 Длина улицы Вещественное v_real_003 2 Наименование Строка v_str_004 2 Площадь Вещественное v_real_005 3 Наименование Строка v_str_005 3 Число жителей Целое v_int_00
В табличке ASSOCIATION:
id Наименование Id коллекции id связанной коллекции1 1 Улица-Район 1 22 2 Район-Город 2 3

Все, метаданные описаны.

Далее - данные:

В табличке Tuple:
id collection_id v_str_00 v_real_00 v_int_001 3 Санкт-Петербург 52256902 2 Василеостровский209 5873 2 Адмиралтейский1635914 2 Московский 3506025 1 Биржевая линия 2606 1 Подольская улица 7727 1 Проспект Космонавтов 4900

Теперь реализуем связи, табличка LINK:
tuple_id association_id linked_tuple_id Примечание512 Биржевая линия находится в Василеостровском районе613 Подольская улица находится в Адмиралтейском районе714 Проспект Космонавтов находится 221 Василеостровский район находится в Санкт-Петербурге321 Адмиратейский район находится в Санкт-Петербурге421 Московский район находится в Санкт-Петербурге

Зачем нужна ASSOCIATION? Связей между одинаковыми сущностями может быть больше, чем одна. Например, связь "Человек-Адрес". Адрес может быть местом фактического жительства, местом рождения, местом регистрации. Соответственно, три независимых связи.
...
Из схемы отброшены разные незначительные мелочи вроде поведения при удалении и т.п.

Есть отдельные механизмы, облегчающие жизнь при создании гуя. Например, в схеме Улица-(связь 1)-Район-(связь 2)-Город можно указать, что связь 2 является определяющей для связи 1. Сие в гуи-интерфейсе при выборе улицы автоматом потребует сперва выбрать город, потом район (из списка именно в этом городе), а уж потом - улицу (из списка именно в этом районе этого города), а не копаться в гигантском списке улиц всей России.
...
Вроде основное описал. А зачем тебе? :)
...
Рейтинг: 0 / 0
63 сообщений из 63, показаны все 3 страниц
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Что лучше: FK или триггеры проверки целостности?
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]