admin管理员组文章数量:1122832
I have a table named urls
:
id | name |
---|---|
1 | url1 |
2 | url2 |
I have a table named urls
:
id | name |
---|---|
1 | url1 |
2 | url2 |
This urls
table is referenced by two other tables documents
and doctypes
.
documents
:
id | reference |
---|---|
1 | kl/dkj/192 |
2 | kl/dji/982 |
doctypes
:
id | name |
---|---|
1 | document1 |
2 | document2 |
documents
and doctypes
have other columns also. I want to add urls for both documents
and doctypes
table. My requirement is to know how can I establish a relationship between urls
and these tables. I think when I list document
and doctypes
in my app, I don't want to display urls, but when I click on detailed view, I can join document
and urls
tables for knowing url value.
Now I designed relationship like this - document_urls
:
document_id | url_id |
---|---|
1 | 3 |
2 | 2 |
doctype_urls
:
doctype_id | url_id |
---|---|
1 | 3 |
2 | 2 |
My question: is this a good approach?
I also think I could have altered documents table to reference urls table like this
id | reference | url_id |
---|---|---|
1 | kl/djkf/34 | 1 |
2 | kl/de/3445 | 3 |
For this approach my question: is it a good approach, since url
column is not a required column, and I was not listing url details when I list my documents.
2 Answers
Reset to default 1The only way to determine the best design for a database schema is to analyse the entities and relationships you want to represent.
Firstly, be careful of confusing data types with entities - just because many things have an attribute called "URL", with similar-looking content, does not necessarily mean that they should reference a URL entity. As an example, imagine having a "users" table and a "products" table; both might have a "name" attribute, but it would be very unusual to consider "name" an entity on its own, and have a single table called "names", because "user name" and "product name" don't have any natural connection.
If the "document URL" is actually always added to a fixed prefix of "/documents/", and a "doctype URL" is always added to a fixed prefix of "/doctypes/", they can be represented as separate entities. If you want to represent a single pool of URLs, which can be assigned ad hoc for various different purposes, you need a separate "URL" entity.
Secondly, you need to determine the "cardinality" of the relationships. Can one document have zero URLs, multiple URLs, or always exactly one? Can one URL refer to zero documents, multiple documents, or always exactly one?
With the answers to these questions in mind, you can choose between a number of schemas:
- If the relationships are "each document has exactly one document_url", and "each doctype has exactly one doctype_url", you can have a non-nullable "url" column on "documents" and "doctypes"
- If one or both relationships are "... can have zero or one ...", you can make the column nullable
- If you decide there is a separate URL entity, you need an extra table and extra constraints:
- A foreign key from "urls" to "documents" models the relationship "one URL represents exactly one document"; same for "doctypes"
- To also represent "one document has exactly one URL", you can add a Unique Constraint on the "document_id" foreign key (and similar on "doctype_id")
- To represent "each URL refers to either one document or one doctype", you can add a Check Constraint on the table, e.g.
NOT (document_id IS NULL AND doctype_id IS NULL)
(reword with care, remembering De Morgan's laws!)
The easiest solution would be to put the urls in the tables:
CREATE TABLE doctypes
(
id BIGINT GENERATED ALWAYS AS IDENTITY,
name VARCHAR(100) NOT NULL,
url VARCHAR(100) NOT NULL
);
CREATE TABLE documents
(
id BIGINT GENERATED ALWAYS AS IDENTITY,
id_doctype BIGINT NOT NULL REFERENCES doctypes(id),
reference VARCHAR(100) NOT NULL,
url VARCHAR(100)
);
You can even add unique constraints on the urls:
ALTER TABLE doctype ADD CONSTRAINT unique_doctype_url UNIQUE (url);
ALTER TABLE documents ADD CONSTRAINT unique_doctype_url UNIQUE (url);
The only thing that this does not do is guarantee that there is no url used both for a doctype and a document at the same time. If you must guarantee that, then remove the urls and add a url table instead:
CREATE TABLE urls
(
id BIGINT GENERATED ALWAYS AS IDENTITY,
url VARCHAR(100) NOT NULL UNIQUE,
id_doctype BIGINT REFERENCES doctypes(id),
id_document BIGINT REFERENCES documents(id),
CONSTRAINT chk_url_one_reference
CHECK((id_doctype IS NULL AND id_document IS NOT NULL) OR
(id_doctype IS NOT NULL AND id_document IS NULL))
);
本文标签: sqlHow to design a table which is referenced by two other tables in postgresStack Overflow
版权声明:本文标题:sql - How to design a table which is referenced by two other tables in postgres - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1736283329a1926934.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
documents
anddoctypes
tables need to have more than one URL, and a single URL can be related to multiple documents or doctypes, this approach is corrent. (ManyToMany). – ABDULLOKH MUKHAMMADJONOV Commented yesterdayurl
is not connected to multipledocument
ordoctypes
. each url is only connected to onedoctypes
ordocuments
. and now i am not sure eachdocuments
have multiple urls. how can i design in either of the case – hafis Commented yesterday