设计数据库用于存储文件

时间:2016-04-04 10:19:36

标签: sql postgresql

我是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. 如何在表KNOWLEDGEBASE中插入一行SQL查询一行,在KNOWLEDGEBASE_FILES中插入多个文件?

1 个答案:

答案 0 :(得分:1)

重新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列为serial列,或者至少为其中的ID创建序列。