What is The best Data model for Add multiple files to The multiple tables? I have for example 5 tables articles, blogs, posts... and for each item I would like to store multiple files. Files table contains only filepaths (not physicaly files).
Example:
Im using The links table, but when I create in the future The new table for example "comments", then I need to add new column to The links table.
Is there a better way of modeling such data?
One way to solve this is to use the table inheritance pattern. The main idea is to have a base table (let's call it content) with general shared information about all the items (e.g., creation date) and most importantly, the relationship with files. Then, you may add additional content types in the future without having to worry about their relation to files, since the content parent type already handles it.
E.g.:
CREATE TABLE flies (
id NUMERIC PRIMARY KEY,
path VARCHAR(100) NOT NULL
);
CREATE TABLE content (
id NUMERIC PRIMARY KEY,
created TIMESTAMP NOT NULL
);
CREATE TABLE links (
file_id NUMERIC NOT NULL REFERENCES files(id),
content_id NUMERIC NOT NULL REFERENCES content(id),
PRIMARY KEY (file_id, content_id)
);
CREATE TABLE articles (
id NUMERIC PRIMARY KEY REFERENCES content(id),
title VARCHAR(400),
subtitle VARCHAR(400)
);
-- etc...
Related
In my database, I have a table for "tags". So, in my main table, I want to give each item multiple tags.
For example, if my main table is dog, I want to add tags for small brown and mean. But in my tags table, I might have 50 possible tags. Each dog can have as many tags if I want.
How do I do that?
I don't really want to create one column for each tag in the main table with a boolean. Is there a way to specify multiple tags in one field?
(I'm rather not used to working with databases, so this probably sounds stupid.)
In the end, the goal is to be able to get all the dogs that match a particular tag.
You are describing a many-to-many relationship between dogs and tags. You would typically represent that with a bridge table, that references the two other referential tables, that store dogs and tags.
Assuming the following structures for the referential tables:
create table dogs (
dog_id int primary key,
name text
);
create table tags (
tag_id int primary key,
name text
);
You would create the bridge table as:
create table dogs_tags (
dog_id int references dogs(dog_id),
tag_id int references tags(tag_id),
primary key (dog_id, tag_id)
);
I have a table Tags which has 2 columns:
name VARCHAR(50)
group_id INT
The combination on both cannot be repeated so I use a composite key to make sure that the combination of name and group_id cannot be used 2 times.
But since the name is a varchar column, it is not a very good option for querying the database, so if I use an id column which is not a primary key but is an autoincrement, I can search for only one column in the database will be ok?
The table will be like this:
name VARCHAR(50) PRIMARY KEY,
group_id INT PRIMARY KEY
id autoincrement NOT NULL
I never seen this before and it looks like a solution, but I really need other point of view before applying this solution.
I have to import the tags from a file and those tags have a many many relation with another table that I'm also importing from the file, just to illustrate the file structure is like this:
enterprises |TagGroup1 |TagGroup2 |...TagGroupN
Google |t1.1,t1.2 |t2.1,t2.2 |tN.1,tN.2
canonical |t1.1.1 |t2.1,t2.2 |tN.1,tN.2
given this file I'll explain that a tag belongs to a group and an enterprise has tags so when I import the file I import the group and then create the tags in bulk, them import enterprises but when I need to import the relation between tags and enterprises if I have need the tag numeric id that will force me to insert the tags one by one which is not a good idea at all, but if I had the name and group ID as key I not longer need to wait for the tag's ID...
sorry this is to long and I'm trying to explain my problem but I don't know if I succeeded in making this simple to understand
[…] so I use a composite key to make sure that the combination of name and group_id cannot be used 2 times.
You are describing a need for a constraint; that doesn't need to be a key at all. When defining a table you can specify a constraint that multiple fields need to be unique together:
CREATE TABLE tag (
name varchar(50),
group_id int,
UNIQUE (name, group_id) );
That way you get the RDBMS enforcing those columns have a unique pair of values on each record, without implying that they are a key for retrieval.
So then you are free to nominate whatever primary key you like. Because you want the id field to be primary key, go for it:
CREATE TABLE tag (
name varchar(50),
group_id int,
id serial NOT NULL,
UNIQUE (name, group_id),
PRIMARY KEY (id) );
Let's hope my explanation is clearer than the title.
I have a set of files. Each file contains a variable number of papers/forms. So I have a table called files, with an fid.
For the sake of simplicity, let's say we have only 3 different forms, each contains its own set of data. So I have 3 tables, FormA, FormB and FormC, with their primary keys Aid, Bid, and Cid respectively.
The file can contain for example, 2 A forms and 1 B form, or 1 of each form, or 3 A forms, 2 B forms, 2 C forms. You get the idea, variable number of forms, and might include more than 1 of the same type.
How to properly represent such relationship in SQL? If it matters, I'm using PostGreSQL.
In PostgreSQL here is how I would do this. Note I am using dangerous (non-beginner/advanced) tools, and it is worth understanding the gotchas.
Now since there are a number of tables here, the question is how we manage the constraints. This is a little convoluted but here is what I would do:
CREATE TABLE file (...);
-- add your tables for tracking form data here....
CREATE TABLE file_to_form (
file_id int NOT NULL;
refkey int NOT NULL,
form_class char NOT NULL
CHECK NOINHERIT (file_id IS NULL)
); -- this table will never have anything in it.
CREATE TABLE file_to_form_a (
PRIMARY KEY (file_id, refkey, form_class)
FOREIGN KEY (refkey) REFERENCES file_a (form_id)
CHECK (form_class = 'a')
) INHERITS (file_to_form);
CREATE TABLE file_to_form_b (
PRIMARY KEY (file_id, refkey, form_class)
FOREIGN KEY (refkey) REFERENCES file_b (form_id)
CHECK (form_class = 'b')
) INHERITS (file_to_form);
-- etc
Now you have a consistent interface for showing which forms are associated with files, and can find them by searching the file_to_form table (which will function similar to a read-only view of all tables that inherit it). This is one of those cases where PostgreSQL's table inheritance really helps, if you take the gotchas seriously and put some thought into how to handle them.
I'm working on new web application contains such as library
books
pictures
files
every kind of the past kinds of sections has different properties in database and i cant store them information inside one data table, so i need to create 3 different tables.
Visitors can comment on books, files and pictures and i want to develop one module for comment and store all comments inside one table, lets call it (comments)
my question is, what the strategy i have to follow to make this done?
I am thinking about create reference column [reference_id] [nvarchar 50]
and i will store the comments like this
files_{id of file}
pictures_{id of picture} and so on... is that would be great method??
thanks
You should use separate ItemId and ItemType.
Additionally you can create table with ItemTypes and store ItemId and ItemTypeId.
Structure like this: pictures_{id of picture} will waste a lot of space and will not help in performance or later code development.
Example: how you cut item type from something like this:
picture_1234
You have to search for "_", convert truncated text to number, and write a lot of SQL code...
I answered a very similar question:
In a StackOverflow clone, what relationship should a Comments table have to Questions and Answers?
In your case, I would recommend creating a single table Commentables:
CREATE TABLE Commentables (
item_id INT AUTO_INCREMENT PRIMARY KEY
item_type CHAR(1) NOT NULL,
UNIQUE KEY (item_id, item_type)
);
Then each of Books, Pictures, Files has a 1:1 relationship to Commentables.
CREATE TABLE Books (
book_id INT PRIMARY KEY, -- but not auto-increment
item_type CHAR(1) NOT NULL DEFAULT 'B',
FOREIGN KEY (book_id, item_type) REFERENCES Commentables(item_id, item_type)
);
Do the same for Pictures and Files. The item_type should always be 'B' for books, always 'P' for pictures, always 'F' for files. Therefore you can't have a book and a picture reference the same row in Commentables.
Then your comments can reference one table, Commentables:
CREATE TABLE Comments (
comment_id INT AUTO_INCREMENT PRIMARY KEY,
item_id INT NOT NULL,
FOREIGN KEY (item_id) REFERENCES Commentables (item_id)
);
What is the best way to translate the following problem in SQL table structure:
In a file transfer application, I have a master table with an "Upload type" field. Depending on the value of that field (FTP, SFTP, HTTPS, FS copy) the record is to be linked with other entries in the appropriate table (FTPsites, HTTPSSites, etc.) containing the relevant details.
This master table has several similar "switch" fields (upload, download, encryption, decryption, and a few application-related ones).
Currently, the table has a different field for each possible target table. This allows me to keep integrity constrains on the table but that's a lot of fields which are going to be NULL.
Is there a better schema for solving that problem ?
In case it's relevant, the target DB is MS SQL 2008
What you are describing is a database design issue akin to implementing table inheritance (where your master table is the parent and your type-specific tables are the children). You can see a really good explanation of how to implement table inheritance with SQL Server 2005/2008 here:
http://www.sqlteam.com/article/implementing-table-inheritance-in-sql-server
...but I will adapt the design pattern in that article to your specific case below.
First, you need a new table to hold your possible list of UploadTypes:
create table UploadType
(
UploadTypeID int primary key,
UploadTypeDesc varchar(50)
)
Now, make sure your MasterTable has a foreign key to the UploadType table and add an additional UNIQUE constraint to your master table on the fields MasterTableID and UploadTypeID:
create table MasterTable
(
MasterTableID int primary key,
UploadTypeID int references UploadType(UploadTypeID),
-- ...Other fields...
constraint MasterTable_AltPK unique (MasterTableID,UploadTypeID)
)
Assuming you have inserted values into the UploadType table so that HTTP uploads have an UploadTypeID = 1, FTP uploads have an UploadTypeID = 2, and SFTP uploads have an UploadTypeID = 3, you can set now up your upload-specific tables as follows (explanation at the end):
create table HTTPSites
(
HTTPSiteID int primary key,
UploadTypeID as 1 persisted, -- computed column; explanation below
-- ...Other fields...
foreign key (MasterTableID, UploadTypeID) references MasterTable(MasterTableID, UploadTypeID)
)
create table FTPSites
(
FTPSiteID int primary key,
UploadTypeID as 2 persisted,
-- ...Other fields...
foreign key (MasterTableID, UploadTypeID) references MasterTable(MasterTableID, UploadTypeID)
)
create table SFTPSites
(
SFTPSiteID int primary key,
UploadTypeID as 3 persisted,
-- ...Other fields...
foreign key (MasterTableID, UploadTypeID) references MasterTable(MasterTableID, UploadTypeID)
)
Each of these type-specific tables includes a dual-key foreign key to the master table on the MasterTableID and the UploadTypeID (this is how you get your referential integrity), and each includes a computed-column for the UploadTypeID that reflects the specific type of upload stored in that table. Each of these computed columns will force any new records inserted into these type-specific tables to be created with a specific UploadTypeID, therefore locking the tables to a specific upload type.
The beauty of this design is that it gives you database-driven referential constraints that meets all of your data integrity requirements without a lot of nulls. You can see the above posted article for detailed examples of how this schema prevents data integrity problems during inserts, deletes, etc. if you want to go deeper.