MySQL, InnoDB: two-column unique constraint with one column in parent table - mysql

In a child table, I need to enforce a unique constraint with a composite key where one of the two columns is in the parent table.
The situation is that in my application users can have multiple accounts of different types. One of these types represents an account from a foreign source that has its own id (foreign_account_id), the others are internal and only have the account_id primary key. Now, different users can be connected to the same account from the foreign source, but each user only once. So i need a composite unique key over users_id and foreign_account_id.
Is that possible or is there a good workaround for this (e.g. would it be good practice to just repeat the column users_id in the child table)?
This is the structure
accounts (parent)
id (primary)
users_id
description
....
accounts_foreign (child)
accounts_id (primary, fk for accounts)
foreign_account_id
info1
info2
...

Related

Make Foreign key unique that is referencing to a unique primary key?

I am creating a database in mysql and my question is if i should make a foreign key that is referencing to an already unique Primary key also unique?
Depends. Here are the two possible scenarios:
1:N Table homes has a foreign key owner_id to table owners, stating which owner owns a home. Since an owner can own more than one home, some homes might have the same owner_id, so it shouldn't be unique.
1:1 Table tax_records has a foreign key owner_id to table owners, stating who is the owner of the tax record. Since an owner can have only one tax record, the owner_id should show up only once in the tax_records table, and therefore should be unique. Have in mind that 1:1 relationships can be implemented in 2 ways, you could also have a foreign key tax_record_id in the owners table. The right choice is to put the foreign key to the entity that "belongs" to the other entity. E.g. a tax record belongs to an owner, so you should have a foreign key owner_id in the tax_records table.

sql unique composite foreign key

I have 2 tables:
group_config (id_group_config, owner_id, name_group_config)
group (id_group, id_group_config, name_group) - id_group_config is FK to group_config
So basically, a user (owner_id) creates a group_config, then creates a group which references this group_config. Pretty standard, but I want a constraint that the name_group must be unique per owner_id.
Only way I found to do this would be to replicate the owner_id on the group table too, which could cause inconsistencies.
Am I missing something?
thanks
Since a group_config can't exist without owner_id You should make the PK of group_config a composite PK consisting of owner_id and group_config_id. You need to be careful about referential integrity constraints here e.g. what happens when you delete an owner?
This will automatically make the FK in group be that composite key.
To make the name_group unique per owner in group table, you create a unique index composed of the columns owner_id and the name_group.

One or Two primary keys for a database

I have two columns in a table that will always be unique, vendor_identifier and product_identifier. Both of them are about equal length. Should I add both of them as primary keys, or only one, or some variant of that? Is there any difference between adding one or two here?
are que querying by both keys? or maybe one at the time?
depending on the answer you can do a composite index or two different indexes.. if you are adding two different indexes remember that the most used one should be at the left
but basically all depends of the architecture of your app / and the DB schema you choose to use...
In MySql the primary key gets the clustered index, so you should make the primary key be the unique identifier you will most frequently query. (This includes joins.)
It's not quite clear from your question if those two fields are each unique on their own, or if they're only guaranteed to be unique as a combination. If they should always be unique individually, then at the least you should put a separate unique index on each of them. If they're only unique in combination, then that's your only guarantee of uniqueness and the primary key should be the two of them together as a single key.
You can only have one be the primary key. You can have the other be a UNIQUE key.
Whichever you prefer to be the default PRIMARY KEY is your choice.
There is something you need to ask yourself:
Will a table that has both columns allow multiple products?
Will a table that has both columns allow multiple vendor?
Will a table that has both columns allow the tuple (vendor,product) one or more times?
Answering these rhetorial questions will help you decide whether a table has one of the following as the PRIMARY KEY
vendor_identifier
product_identifier
vendor_identifier,product_identifier
Consider the following:
(1) is the combination of vendor_id and product_id also guaranteed to be unique?
(2) will you always search with both vendor_id and product_id?
A compound primary key only makes sense if you can answer yes to both. If you cannot, then just select the one with higher cardinality to be the primary key and make a secondary index on the other.
since you dont describe your tables - i'm going to suggest that you actually have 3 tables here:
VENDOR
--------
vendor_id
other_cols
PRODUCT
---------
product_id
other_cols
VENDOR_PRODUCT
--------------
vendor_id
product_id
price-description-dates etc.
in this case - the VENDOR_ID in the VENDOR table is the PK.
the PRODUCT_ID in the PRODUCT table is the PK (for that table)
the VENDOR_ID in the VENDOR_PRODUCT table is a foreign key
the PRODUCT_ID in the VENDOR_PRODUCT table is a foreign key
you may choose to enforce uniqueness on the pair VENDOR_ID, PRODUCT_ID in the VENDOR_PRODUCT table, or not as you choose. If unique, they may be acting as a COMPOUND KEY in that table. If you need to reference rows in the VENDOR_PRODUCT from somewhere else in your schema, then you may consider a new single value primary key instead of copying these two columns to the new table and trying to get the FK definitions correct.
Assuming your vendor_identifier is a foreign key relating to a vendor table, and product_identifier is a foreign key relating to a product table, I'd create an autonumber field (vendor_product_identifier, perhaps?) to be the primary key of the table that has both vendor_id and product_id in it. Then I'd place a unique index on the combination of vendor_id and product_id.
So, the general idea would be:
Vendor
------
vendor_identifier PK
name
phone
etc...
Product
-------
product_identifier PK
name
category
etc...
Vendor_Product
--------------
vendor_product_identifier //"AUTONUMBER PK"
vendor_identifier //"FK to Vendor, and part of COMBOINDEX1"
product_identifier //"FK to Vendor, and part of COMBOINDEX1"
etc...
Having a new key for vendor_product gives you just one key to pass around on the application side to refer to a combination of both vendor and product. Having a unique index on the combination of vendor_id and product_id in the vendor_product table ensures that you won't get duplicate entries for that combination of data either (has to be a unique index though, not just an index).

To use auto-increment in MySQL or not?

I have read certain places that it is a good practice to typically use an auto-incrementing Primary key for most MySQL tables, rather than simply relying on a non-increment field that will be enforced to be unique.
My question is specifically about a User table, and a table connected to it by a Foreign Key. Here's the schema:
TABLE Users {
id
name
...
}
TABLE Authors {
user_id (FK)
author_bio
}
Should the Authors table have its own auto-incrementing primary key as well, or should it rely on the user_id foreign key as a primary key?
ALSO
Are there noticeable performance reasons to NOT use the auto-incrementing id as the Primary?
It's not either-or. If you use an auto increment primary key, and you have candidate keys that need to enforce constraints, then your schema should have both.
Both your user and author tables should have individual primary keys. (Every table must have a primary key.) I would not use the foreign key as the primary key. If that truly is the case, I wouldn't have a separate author table; I'd put those columns in the user table.
PS - My naming preference is singular for tables. It should be user and author tables. They happen to contain multiple rows, but a single row means a single entity.
You most definitely want the Authors table to have its own primary key such as authors_id, and then have user_id as a foreign key.
It depends on what you're trying to accomplish. If every author maps to exactly one user (and you're sure this isn't going to change), you can get away with having user_id as a primary key. If not, you'll need an independent primary key for Authors.
(Note that the reverse relation doesn't have to be true: not every user has to map to an author.)

Is it necessary that the Foreign key of some table should be the candidate key of the same table?

Foreign key should necessarily be a candidate key for a table (say table1)? I know that Foreign key references primary key of some other table (say table2). But for the table1, is it necessary that it should be candidate key?
By definition a foreign key is required to reference a candidate key in the target table (table2 in your question). A foreign key does not have to be a candidate key in the referencing table or be part of a candidate key in that table.
No. You can have a 1:N relationship, the FK requirement just says that the field has to exist in the other table. Whether that field is unique or not, does not matter.
For reference:
a candidate key is an alternative to a PK, it can be one field or the combination of fields (as in a concatenated key)
all this establishes is that there is more than one way to uniquely identify a record of the table
a good alternative to an employee_id might be ssn (social security number)
a concatenated key is multiple fields that make up the uniqueness of a record, which can either be an alternative to a PK, or together, act as the PK
because RDBMSs follow at least 1NF, all the fields of the table could be used as the concatentated key
Note: this is a bad choice and only serves as an example
think of an employee_id field as the one PK of the table, but the combination of firstname,lastname, and startdate would probably uniquely identify everyone on your employees table
Note: this is an example, there would probably be better alternatives to this in practice