2016-04-04 3 views
-1

Я новичок в PostgreSQL и SQL. Я работаю над небольшим приложением, которое используется для хранения файлов. До сих пор я создал эти таблицы:Дизайн базы данных для хранения файлов

CREATE TABLE KNOWLEDGEBASE(
ID INTEGER NOT NULL, 
NAME TEXT, 
SHORT_DESCRIPTION TEXT, 
DESCRIPTION TEXT, 
CONTENT TEXT, 
LAST_UPDATED DATE, 
CREATED DATE 
) 
; 

-- ADD KEYS FOR TABLE KNOWLEDGEBASE 

ALTER TABLE KNOWLEDGEBASE ADD CONSTRAINT KEY9 PRIMARY KEY (ID) 
; 

-- TABLE KNOWLEDGEBASE_FILES 

CREATE TABLE KNOWLEDGEBASE_FILES(
ID INTEGER NOT NULL, 
DOC_ID INTEGER, 
FILE BYTEA 
) 
; 

-- CREATE INDEXES FOR TABLE KNOWLEDGEBASE_FILES 

CREATE INDEX IX_RELATIONSHIP4 ON KNOWLEDGEBASE_FILES (DOC_ID) 
; 

-- ADD KEYS FOR TABLE KNOWLEDGEBASE_FILES 

ALTER TABLE KNOWLEDGEBASE_FILES ADD CONSTRAINT KEY10 PRIMARY KEY (ID) 
; 

-- CREATE RELATIONSHIPS SECTION ------------------------------------------------- 

ALTER TABLE KNOWLEDGEBASE_FILES ADD CONSTRAINT RELATIONSHIP4 FOREIGN KEY (DOC_ID) REFERENCES KNOWLEDGEBASE (ID) ON DELETE CASCADE ON UPDATE CASCADE 
; 

У меня есть несколько вопросов:

  1. Является ли этот внешний ключ правильно между двумя таблицами? Я хочу иметь одну запись в таблице KNOWLEDGEBASE и несколько файлов, прикрепленных к этой записи.

  2. Как я могу вставить с одним SQL-запросом одну строку в таблице KNOWLEDGEBASE и несколько файлов в KNOWLEDGEBASE_FILES?

+0

Могу ли я узнать, почему я получаю отрицательный отзыв? –

+0

Знаете ли вы, что PostgreSQL поддерживает большие объекты? http://www.postgresql.org/docs/current/static/largeobjects.html. И знаете ли вы, что дайвер DOS PosgreSQL поддерживает большой объект? https://jdbc.postgresql.org/documentation/publicapi/index.html. Я думаю, что поддержка родных больших объектов лучше для хранения файлов в базе данных с использованием типа bytea –

+0

Вы имеете в виду тип данных OID или что-то еще? –

ответ

1

re 1: да внешний ключ правильный.

re 2: В общем, я бы рекомендовал использовать несколько операторов в одной транзакции. Это, как правило, проще в обращении:

begin transaction; 
insert into knowledgebase 
    (id, name, short_description, description, content, last_updated, created) 
    values 
    (42, 'First document', 'a short one', 'a longer description', 'Not much to say', current_date, current_date); 

insert into knowledgebase_files 
    (id, doc_id, file) 
values 
    (42, 1, ...), 
    (42, 2, ...), 
    (42, 3, ...); 

commit; 

Если вы действительно нужно сделать это в одном операторе SQL, необходимо использовать общее табличное выражение:

with new_kb as (
    insert into knowledgebase 
    (id, name, short_description, description, content, last_updated, created) 
    values 
    (42, 'First document', 'a short one', 'a longer description', 'Not much to say', current_date, current_date) 
    returning id 
) 
insert into knowledgebase_files 
    (id, doc_id, file) 
values 
    ((select id from new_kb), 1, ...), 
    ((select id from new_kb), 2, ...), 
    ((select id from new_kb), 3, ...) 
; 

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

Если вы используете JDBC, вам необходимо использовать PreparedStatement и т. Д. setBinaryStream() для передачи содержимого файла.

Возможно, вы захотите сделать столбец knowledgebase.id aserial или, по крайней мере, создать последовательность для идентификаторов.

+0

Спасибо за хороший ответ. Я собираюсь использовать Java с PostgreSQL –

+0

Что вы подразумеваете под 'knowledgebase.id последовательной колонкой'? –

+0

@PeterPenzov: http://www.postgresql.org/docs/current/static/datatype-numeric.html#DATATYPE-SERIAL –

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