COMMENT ON COLUMN CTR_MEDIA.T_CARRIER.PLACE>_ID IS 'Ссылка на место хранения';Надо признаться, что эту программу я начал делать полтора года назад, и сейчас у меня уже есть вполне работоспособное приложение. Поэтому при описании процесса создания программы я буду опускать свои искания и ошибки и буду показывать сразу готовые результаты. :)
Так я опущу мысли, рассуждения и ход создания структуры таблиц медиатеки, а сразу покажу, что у меня есть на текущий момент. Все таблицы представлены на следующей диаграмме, которую я создал в SQL Developer: А следующий листинг показывает скрипт для создания таблиц: CREATE TABLE CTR_MEDIA.T_AUTHOR ( ID NUMBER(10,0) NOT NULL ENABLE, NAME VARCHAR2(250 BYTE) NOT NULL ENABLE, NOTE CLOB, CONSTRAINT T_AUTHOR_PK PRIMARY KEY (ID) USING INDEX TABLESPACE MEDIATEK ENABLE ) TABLESPACE MEDIATEK LOB (NOTE) STORE AS LS_AUTHOR_NOTE (TABLESPACE MEDIATEK DISABLE STORAGE IN ROW);
COMMENT ON COLUMN CTR_MEDIA.T_AUTHOR.ID IS 'Идентификатор'; COMMENT ON COLUMN CTR_MEDIA.T_AUTHOR.NAME IS 'Имя'; COMMENT ON COLUMN CTR_MEDIA.T_AUTHOR.NOTE IS 'Описание'; COMMENT ON TABLE CTR_MEDIA.T_AUTHOR IS 'Один человек или коллектив, который принимал участие в создании произведения и/или носителя';
CREATE TABLE CTR_MEDIA.T_CARRIER_KIND ( ID NUMBER(2,0) NOT NULL ENABLE, NAME VARCHAR2(250 BYTE) NOT NULL ENABLE, CONSTRAINT T_CARRIER_KIND_PK PRIMARY KEY (ID) USING INDEX TABLESPACE MEDIATEK ENABLE ) TABLESPACE MEDIATEK;
COMMENT ON COLUMN CTR_MEDIA.T_CARRIER_KIND.>ID IS 'Идентификатор'; COMMENT ON COLUMN CTR_MEDIA.T_CARRIER_KIND.>NAME IS 'Название'; COMMENT ON TABLE CTR_MEDIA.T_CARRIER_KIND IS 'Справочник видов носителей: книга, газета, пластинка, фотография и т.п.';
CREATE TABLE CTR_MEDIA.T_PLACE ( ID NUMBER(10,0) NOT NULL ENABLE, NAME VARCHAR2(250 BYTE) NOT NULL ENABLE, NOTE CLOB, IMAGE CTR_MEDIA.O_FILE , CONSTRAINT T_PLACE_PK PRIMARY KEY (ID) USING INDEX TABLESPACE MEDIATEK ENABLE ) TABLESPACE MEDIATEK LOB (NOTE) STORE AS LS_PLACE_NOTE (TABLESPACE MEDIATEK DISABLE STORAGE IN ROW);
COMMENT ON COLUMN CTR_MEDIA.T_PLACE.ID IS 'Идентификатор'; COMMENT ON COLUMN CTR_MEDIA.T_PLACE.NAME IS 'Название'; COMMENT ON COLUMN CTR_MEDIA.T_PLACE.NOTE IS 'Описание'; COMMENT ON COLUMN CTR_MEDIA.T_PLACE.IMAGE IS 'Изображение'; COMMENT ON TABLE CTR_MEDIA.T_PLACE IS 'Место, где хранится носитель: комната, шкаф, полка и тому подобное.';
CREATE TABLE CTR_MEDIA.T_ROLE ( ID NUMBER(3,0) NOT NULL ENABLE, NAME VARCHAR2(250 BYTE) NOT NULL ENABLE, CONSTRAINT T_ROLE_PK PRIMARY KEY (ID) USING INDEX TABLESPACE MEDIATEK ENABLE ) TABLESPACE MEDIATEK;
COMMENT ON COLUMN CTR_MEDIA.T_ROLE.ID IS 'Идентификатор'; COMMENT ON COLUMN CTR_MEDIA.T_ROLE.NAME IS 'Название'; COMMENT ON TABLE CTR_MEDIA.T_ROLE IS 'Справочник ролей авторов';
CREATE TABLE CTR_MEDIA.T_TEMPLATE ( ID NUMBER(10,0) NOT NULL ENABLE, KIND_ID NUMBER(2,0) NOT NULL ENABLE, SORT_SEQ NUMBER(2,0) NOT NULL ENABLE, NAME VARCHAR2(250 BYTE) NOT NULL ENABLE, RULE VARCHAR2(250 BYTE), CONSTRAINT T_TEMPLATE_PK PRIMARY KEY (ID) USING INDEX TABLESPACE MEDIATEK ENABLE, CONSTRAINT T_TEMPLATE_KIND_FK FOREIGN KEY (KIND_ID) REFERENCES CTR_MEDIA.T_CARRIER_KIND (ID) ON DELETE CASCADE ENABLE ) TABLESPACE MEDIATEK;
COMMENT ON COLUMN CTR_MEDIA.T_TEMPLATE.ID IS 'Идентификатор'; COMMENT ON COLUMN CTR_MEDIA.T_TEMPLATE.KIND>_ID IS 'Ссылка на тип носителя'; COMMENT ON COLUMN CTR_MEDIA.T_TEMPLATE.SORT>_SEQ IS 'Номер атрибута по порядку - для сортировки'; COMMENT ON COLUMN CTR_MEDIA.T_TEMPLATE.NAME IS 'Название атрибута'; COMMENT ON COLUMN CTR_MEDIA.T_TEMPLATE.RULE IS 'Правило для проверки правильности (регулярное выражение)'; COMMENT ON TABLE CTR_MEDIA.T_TEMPLATE IS 'Шаблон дополнительного атрибута медианосителя';
CREATE INDEX CTR_MEDIA.T_TEMPLATE_KIND>_I ON CTR_MEDIA.T_TEMPLATE (KIND_ID) TABLESPACE MEDIATEK;
CREATE TABLE CTR_MEDIA.T_AUTHOR_ROLE ( ID NUMBER NOT NULL ENABLE, ROLE NUMBER(3,0) NOT NULL ENABLE, AUTHOR NUMBER(10,0) NOT NULL ENABLE, CARRIER NUMBER(10,0) NOT NULL ENABLE, SORT_SEQ NUMBER(2,0), CONSTRAINT T_AUTHOR_ROLE_PK PRIMARY KEY (ID) USING INDEX TABLESPACE MEDIATEK ENABLE, CONSTRAINT T_AUTHOR_ROLE_ROLE_FK FOREIGN KEY (ROLE) REFERENCES CTR_MEDIA.T_ROLE (ID) ENABLE, CONSTRAINT T_AUTHOR_ROLE_AUTHOR_FK FOREIGN KEY (AUTHOR) REFERENCES CTR_MEDIA.T_AUTHOR (ID) ENABLE, CONSTRAINT T_AUTHOR_ROLE_CARRIER_FK FOREIGN KEY (CARRIER) REFERENCES CTR_MEDIA.T_CARRIER (ID) ON DELETE CASCADE ENABLE ) TABLESPACE MEDIATEK;
COMMENT ON COLUMN CTR_MEDIA.T_AUTHOR_ROLE.I>D IS 'Идентификатор'; COMMENT ON COLUMN CTR_MEDIA.T_AUTHOR_ROLE.R>OLE IS 'Ссылка на справочник ролей'; COMMENT ON COLUMN CTR_MEDIA.T_AUTHOR_ROLE.A>UTHOR IS 'Ссылка на автора'; COMMENT ON COLUMN CTR_MEDIA.T_AUTHOR_ROLE.C>ARRIER IS 'Ссылка на носитель'; COMMENT ON COLUMN CTR_MEDIA.T_AUTHOR_ROLE.S>ORT_SEQ IS 'Номер для сортировки'; COMMENT ON TABLE CTR_MEDIA.T_AUTHOR_ROLE IS 'Роль автора в создании произведения или носителя: писатель, переводчик, иллюстратор, композитор, издатель и т.п.';
CREATE UNIQUE INDEX CTR_MEDIA.T_AUTHOR_ROLE_I ON CTR_MEDIA. T_AUTHOR_ROLE (ROLE, AUTHOR, CARRIER) TABLESPACE MEDIATEK ; CREATE UNIQUE INDEX CTR_MEDIA.T_AUTHOR_ROLE_P>K ON CTR_MEDIA. T_AUTHOR_ROLE (ID) TABLESPACE MEDIATEK;
CREATE TABLE CTR_MEDIA.T_CARRIER ( ID NUMBER(10,0) NOT NULL ENABLE, NAME VARCHAR2(250 BYTE) NOT NULL ENABLE, CREATED DATE, NOTE CLOB, KIND NUMBER(2,0) NOT NULL ENABLE, PLACE_ID NUMBER(10,0), CONSTRAINT T_CARRIER_PK PRIMARY KEY (ID) USING INDEX TABLESPACE MEDIATEK ENABLE, CONSTRAINT T_CARRIER_KIND_FK FOREIGN KEY (KIND) REFERENCES CTR_MEDIA.T_CARRIER_KIND (ID) ENABLE, CONSTRAINT T_CARRIER_PLACE_FK FOREIGN KEY (PLACE_ID) REFERENCES CTR_MEDIA.T_PLACE (ID) ENABLE ) TABLESPACE MEDIATEK LOB (NOTE) STORE AS LS_CARRIER_NOTE (TABLESPACE MEDIATEK DISABLE STORAGE IN ROW);
COMMENT ON COLUMN CTR_MEDIA.T_CARRIER.ID IS 'Идентификатор'; COMMENT ON COLUMN CTR_MEDIA.T_CARRIER.NAME IS 'Название'; COMMENT ON COLUMN CTR_MEDIA.T_CARRIER.CREAT>ED IS 'Дата создания'; COMMENT ON COLUMN CTR_MEDIA.T_CARRIER.NOTE IS 'Описание'; COMMENT ON COLUMN CTR_MEDIA.T_CARRIER.KIND IS 'Тип (из справочника)'; COMMENT ON COLUMN CTR_MEDIA.T_CARRIER.PLACE>_ID IS 'Ссылка на место хранения'; COMMENT ON TABLE CTR_MEDIA.T_CARRIER IS 'Носитель информации - книга, журнал, фотоотпечаток, лазерный диск и т.п.';
CREATE INDEX CTR_MEDIA.T_CARRIER_KIND_>I ON CTR_MEDIA.T_CARRIER (KIND) TABLESPACE MEDIATEK ; CREATE INDEX CTR_MEDIA.T_CARRIER_PLACE>_I ON CTR_MEDIA.T_CARRIER (PLACE_ID) TABLESPACE MEDIATEK;
CREATE TABLE CTR_MEDIA.T_CARRIER_IMAGE ( ID NUMBER(10,0) NOT NULL ENABLE, CARRIER NUMBER(10,0) NOT NULL ENABLE, SEQ_ID NUMBER(3,0) NOT NULL ENABLE, IMAGE CTR_MEDIA.O_FILE , NOTE VARCHAR2(250 BYTE), CONSTRAINT T_CARRIER_IMAGE_PK PRIMARY KEY (ID) USING INDEX TABLESPACE MEDIATEK ENABLE, CONSTRAINT T_CARRIER_IMAGE_UK UNIQUE (CARRIER, SEQ_ID) USING INDEX TABLESPACE MEDIATEK ENABLE, CONSTRAINT T_CARRIER_IMAGE_CARRIER_F>K FOREIGN KEY (CARRIER) REFERENCES CTR_MEDIA.T_CARRIER (ID) ENABLE ) TABLESPACE MEDIATEK;
COMMENT ON COLUMN CTR_MEDIA.T_CARRIER_IMAGE>.ID IS 'Идентификатор'; COMMENT ON COLUMN CTR_MEDIA.T_CARRIER_IMAGE>.CARRIER IS 'Ссылка на носитель'; COMMENT ON COLUMN CTR_MEDIA.T_CARRIER_IMAGE>.SEQ_ID IS 'Номер по порядку'; COMMENT ON COLUMN CTR_MEDIA.T_CARRIER_IMAGE>.IMAGE IS 'Изображение'; COMMENT ON COLUMN CTR_MEDIA.T_CARRIER_IMAGE>.NOTE IS 'Краткое описание'; COMMENT ON TABLE CTR_MEDIA.T_CARRIER_IMAGE IS 'Изображения для носителей';
CREATE UNIQUE INDEX CTR_MEDIA.T_CARRIER_IMAGE>_FNAME_I ON CTR_MEDIA.T_CARRIER_IMAGE (IMAGE.FNAME) TABLESPACE MEDIATEK;
CREATE TABLE CTR_MEDIA.T_ATTRIBUTE ( VALUE VARCHAR2(2000 BYTE) NOT NULL ENABLE, CARRIER_ID NUMBER(10,0) NOT NULL ENABLE, TEMPLATE_ID NUMBER(10,0) NOT NULL ENABLE, CONSTRAINT T_ATTRIBUTE_PK PRIMARY KEY (CARRIER_ID, TEMPLATE_ID) USING INDEX TABLESPACE MEDIATEK ENABLE, CONSTRAINT T_ATTRIBUTE_TEMPLATE_FK FOREIGN KEY (TEMPLATE_ID) REFERENCES CTR_MEDIA.T_TEMPLATE (ID) ENABLE, CONSTRAINT T_ATTRIBUTE_CARRIER_FK FOREIGN KEY (CARRIER_ID) REFERENCES CTR_MEDIA.T_CARRIER (ID) ON DELETE CASCADE ENABLE ) TABLESPACE MEDIATEK;
COMMENT ON COLUMN CTR_MEDIA.T_ATTRIBUTE.VAL>UE IS 'Значение дополнительного атрибута'; COMMENT ON COLUMN CTR_MEDIA.T_ATTRIBUTE.CAR>RIER_ID IS 'Ссылка на медианоситель'; COMMENT ON COLUMN CTR_MEDIA.T_ATTRIBUTE.TEM>PLATE_ID IS 'Ссылка на шаблон атрибута'; COMMENT ON TABLE CTR_MEDIA.T_ATTRIBUTE IS 'Дополнительные атрибуты мединосителя. Перечень, названия и правила проверки атрибутов определяются типом медианосителя.';
Основная таблица - это T_CARRIER. Каждая запись в ней описывает один медианоситель - книгу, пластинку, CD и т.п. Тип носителя описывается в таблице T_CARRIER_KIND. От типа зависит набор дополнительных атрибутов, характерный для того или иного носителя. Например, для книги это будет количество страниц, формат, код ISBN; а для DVD - тип (DVD+R, DVD-R, DVD-RW, DVD-DL), вид содержимого (аудио, видео, программы). Шаблоны дополнительных атриботов (названия и правила проверки) хранятся в таблице T_TEMPLATE, а конкретные значения для каждого носителя - в таблице T_ATTRIBUTE.
Каждый носитель может иметь нескольо авторов. Для книги это будут автор текста, издатель, художник-иллюстратор; для грампластинки - автор музыки, звукозаписывающая фирма, завод грампластинок. В общем, идея понятна. :) Причём один и тот же автор может выступать в нескольких ипостасях. Автор текста может быть одновременно и иллюстратором и продьюсером. Поэтому я выделил авторов в отдельную таблицу T_AUTHOR, роли авторов поместил в таблицу T_ROLE. И привязал их к таблице носителей через таблицу связки T_AUTHOR_ROLE. Получилось очень гибко, но громоздко. Возможно, в будущем я изменю эту систему.
Таблица T_PLACE хранит описания мест хранения носителей. Например - полки в книжном шкафу, конверты в папке для CD и тому подобное. А таблица T_CARRIER_IMAGE предназначена для изображений медианосителей. У каждого носителя может быть несколько картинок. Так, для книг я сканирую лицевую и иногда тыльную сторону обложки и отдельно суперобложку, для DVD - лицевую, тыльную сторону коробки, вкладыш с разворотами и сам диск.
Во всех таблицах есть суррогатные первичные ключи - идентификаторы ID, которые получают значения от соответствующих последовательностей в соответствующих триггерах. О них я расскажу позже.
Кроме того, таблицы ссылаются друг на друга с помощью внешних ключей. Для каждого такого ключа создан соответствующий индекс. Всё это можно увидеть в листинге.
|