Do I really need Foreign key when using Pivot table? - mysql

let's say, I have a simple database with 3 tables = posts, categories and post_category (which is pivot table).
posts - ID | title | body | created_at/updated_at
categories - ID | name | created_at/updated_at
post_category - post_id | category_id
The primary key is an ID, but I have not specified a foreign key (in posts). Should I specify the foreign key (category_id) as a column in my posts table, or is it okay to use pivot table (post_category) where I already specified the relationship between those 2 tables?
Thanks in advance!

SQL does not require foreign keys to be explicitly declared, particularly with respect to querying tables. Foreign keys enforce relational integrity. That is, they ensure that tables that should refer to each other actually do refer to each other.
That said, MySQL differs from most databases by actually doing something with a foreign key declaration: MySQL builds a secondary index. This index can be quite handy for queries by improving performance.
However, nothing is required about a foreign key relationship.

Related

Am I supposed to use foreign keys for these 3 tables which are connected?

So I have 3 tables:
Table: Albums
Columns: Id, Name, Description, Author, Folderpath, Thumbnail, Upvotes, Downvotes
Table: AlbumsConnection
Columns: Id, AlbumId, AlbumImagesId
Table: AlbumImages
Columns: Id, InAlbum, Imagepath
So far I've been using these tables without actually using foreign keys. Am I supposed to use foreign keys here? I understand that I'd have to add 2 foreign keys to AlbumsConnection, 1 for each table and each foreign key will reference to the primary keys ( which are the ids ) of the other 2 tables. Is that correct?
Foreign keys help ensure relational integrity of the database. There is no requirement for declaring them explicitly, but it is a good idea, particularly if you are learning to use databases.
The foreign key let's the database know that a column in one table is related to a column in another table. I don't think MySQL's optimizer uses this information explicitly, although it does create an index on the foreign key column (unlike most other databases).
In addition, a declared foreign key relationship can help you deal with changes to the database. It will prevent invalid albums from being inserted into the junction table. If you delete an album, it gives you control over how the deletion and updating is handled (via cascading constraints).

How can I get a list of all columns in the database, along with it's referenced table/column and if it is a primary key with no duplicates? (MYSQL)

Using information_schema, I want the table to look similar to this:
IS_PRIMARY|TABLE_NAME|COLUMN_NAME|REFERENCED_TABLE_NAME|REFERENCED_COLUMN_NAME
------------------------------------------------------------------------------
| | | |
I have a lot of primary keys that are also foreign keys (used for parent-child tables and many-many tables). And I have a lot of foreign keys that are not primary keys and vise versa. I am trying to get a list of all columns, their key-situation, and have no duplicates.
I've been playing around with queries but can't get what I want For example I tried:
SELECT COLUMNS.TABLE_NAME,COLUMNS.COLUMN_NAME,COLUMN_KEY,REFERENCED_TABLE_NAME,REFERENCED_COLUMN_NAME
FROM information_schema.COLUMNS
inner join information_schema.KEY_COLUMN_USAGE
on COLUMNS.TABLE_NAME=KEY_COLUMN_USAGE.TABLE_NAME AND COLUMNS.COLUMN_NAME=KEY_COLUMN_USAGE.COLUMN_NAME
WHERE KEY_COLUMN_USAGE.TABLE_SCHEMA='myDatabase'
But this has duplicates as well as some missing values. The difficulty with trying to get a table that looks like this is that keys that are both a primary key and a foreign key have two rows in the database, but I don't want the duplicate.
Please help!

Mysql table design two primary keys vs one

I was wondering which of following is better design.
I've got these tables
users
ID | NAME
Categories
ID | NAME
Which one is better, this:
users_to_categories
CAT_ID | USER_ID
In this case CAT_ID and USER_ID are primary keys
or one primary key
users_to_categories
ID | CAT_ID | USER_ID
only ID is primary key
I assume that you are trying to create a many-to-many relationship between the two tables with a third table titled Users_to_Categories. If so, then CAT_ID and USER_ID would be foreign key pointers to the primary keys in Users and Categories.
All that being said, I would refer to the answer given in this thread (SQL - many-to-many table primary key). I agree with the answer given here, saying that there is really no advantage to creating a new auto-increment primary key when the combination of the CAT_ID/USER_ID can serve as a primary key itself.
Altought both designs are fine, I recommend go for one single field for key approach.
It's easier for doing queries.
It's also easier when you want to change some details records from a header o parent table to another, just change the parent foreign key.

Is there any benefit to having an auto-incrementing primary key in a MySQL pivot table?

Imagine we have three tables in a MySQL database:
posts
categories
category_post
There is a one-to-many relationship between posts and categories so that a single post may have many categories.
The category_post table is the pivot table between categories and posts and has the following columns:
id (primary key, auto-incrementing, big integer)
category_id
post_id
Let's also imagine that we have 1,000,000 rows in our category_post table.
My question is:
Is there any performance benefit to having the id column in the category_post table or does it just take up extra space?
Posts and categories is probably many-to-many, not one-to-many.
A many-to-many relationship table is best done something like
CREATE TABLE a_b (
a_id ... NOT NULL,
b_id ... NOT NULL,
PRIMARY KEY (a_id, b_id),
INDEX(b_id, a_id) -- include this if you need to go both directions
) ENGINE = InnoDB;
With that, you automatically get "clustered" lookups both directions, and you avoid the unnecessary artificial id for the table.
(By the way, N.B., an implicit PK is 6 bytes, not 8. There is a lengthy post by Jeremy Cole on the topic.)
A one-to-many relationship does not need this extra table. Instead, have one id inside the other table. For example, a City table will have the id for the Country in it.
Having category_id and post_id as a compound primary key will have better performance than having an extra id as a primary key. This is because making it a primary key will also create an index on it automatically. If you really want an extra Id column you can improve performance by manually defining an index on category_id and post_id. There is no benefit of having an extra key column though and this is generally a bad practice.
not having id is good, but when you care about ordering by the pivot table you will need to have id or timestamp in pivot table

PRIMARY and FOREIGN key in one field

I have 3 tables: users, pages and users_pages
Users Table
+----+------+-----
| id | name | ...
+----+------+-----
Pages Table
+----+------+-----
| id | name | ...
+----+------+-----
users_pages table, which says, which user is admin of which page.
+---------+---------+
| user_id | page_id |
+---------+---------+
| 1 | 1 | // means, user 1 is admin of page 1
+---------+---------+
in users_pages table, combination of user_id and page_id is a compound key ( primary key )
Is it possible to define user_id and page_id as foreign key while they both together are primary key?
Yes, Absolutely. You havn't mentioned which relational database you are using, but this is common practice, and allowable in all relational databases i know of.
My attempt at an additional explanation:-
Primary and foreign keys are more like 'theoretical' things rather than hard physical things. When looking at the nuts and bolts, I find it useful to think of only indexes and contraints, not of 'keys' as such
Thinking this way a 'primary key' is actually a combination of two separate things :-
A unique contraint. This checks for and refuses any attempts to
create duplicates.
An index based on the field. This just makes
it much faster to retrieve the record if you use that field to look
it up (select * from table where pkey = 'x')
A 'foreign key' in practice is just a contraint, not much different from the unique key contraint. It checks the records exist in the other table, and refuses any attempts to create records with no corresponding entries in the referred to table.
There is no reason why you cant have multiple contraints on the same field (that it is both unique and exists in another table), and whatever indexes is on the table in no way prevents you from adding any contraint you like. Therefore there is no problem having the same field as part of a primary key and it also have a foreign key contraint.