Multiple Foreign Keys from One Table to Another - database

This is my tables definition :
User
Id
Name
IsAdmin
Ticket
Id
User_id
Admin_id
My admins buy tickets for the users, I have Admin and User in a Table but i have to get two foreign keys from User table in Ticket table.
Is this solution standard and normal, or cause to low performance?

Yes, completely standard. Semantically, the ticket is defined by the user it is for, and the admin who purchased it, so it sounds like your design reflects reality (which is a good thing).

This is more or less standard, though it is somewhat flawed, as there’s nothing to prevent an Admin_Id from being set to a "user" id. (This could be enforced programmatically, though ultimately it might require a trigger.)
Performance-wise, it only really matters when Tickets are created (have to look validate the user ids through a lookup in the User table) or updated (ditto), or when Users are deleted (have to make sure user id is not in use in either column in the Ticket table). The questions become: how big are these tables, how often are any of these actions taken, and (if relevant) are there indexes to support these queries?
Purists would normalize your structures like so:
User
Id -- Primary key. To avoid confusion, this couldbe set to User_id
Name
Admin
Id -- Primary key, with foreign key to User.Id To avoid confusion, this could be set to Admin_id
Ticket
Id -- To avoid confusion, this could be set to Ticket_id
User_id -- with foreign key to User.Id
Admin_id -- with foreign key to Admin.Id
(Admin is a “subtype” of User.)

Related

Are multiple UNIQUE (excl. PK and FK) constraints for one entity a bad smell?

My thought:
A Unique field (not PK) is generally something which can be used to identify a entity as it's unique, event this concern is actually handled by the PK.
Example scenario:
I might use a PK 'id' with a number for identification use in my back end and db. I also might have a Unique field 'name' which is used for identification for a front end user.
This scenario makes it plausible to have a PK and ONE additional Unique field.
By using Unique this way, having multiple Unique fields for one entity, seems to me like a bad smell into the direction, that the db might not have been normalized.
Is this correct? Or what would be a plausible scenario to have multiple Unique fields (excluding PK and FK) within one entity?
For example in an online shop you could make a user have an ID as primary key, his nickname used to identify him on comments he leaves and a shopping_basket_ID which connects him to a shopping basket where he can put things he wants to buy.
All 3 of those are unique and it's a plausible implementation.
Using a table of users as an example (and assuming a surrogate primary key to keep that out of the equation), you might want to enforce that all of these must be unique, since it probably doesn't make much sense to allow duplicates:
user name
email address
SSN/NI number or equivalent
combination of bank and account code
probably more

Database schema design and foreign keys

I'm confused what a schema should be implemented in a following case:
I have two core tables user and company and a set of 'inherited'(in terms of ORM) tables like user_type_1, user_type2 that extend user table with an own unique set of fields. And the same for company_type_1, company_type_2 tables that extend company table with an own unique set of fields.
Also I have a address table. Every User and Company in a system can have own address.
My initial idea was to add address_id FK to address(id) PK to root user and company tables. This way every User or Company in a system can be associated with own address.
My colleague proposed another database schema design where user_id and company_id FKs have to be added to address table.
I'm really confused with this proposal right now. Could you please explain or this design can take a place ?
If you add address_id to the user and company tables, you're adding functional dependencies user_id -> address_id and company_id -> address_id. This would mean that each user or company can be associated with a single address, but each address can potentially be associated with multiple users or companies (unless you add a constraint to prevent that).
Your colleague's proposal to add user_id and company_id to the address table adds functional dependencies address_id -> user_id and address_id -> company_id meaning each address can be associated with one user, one company or both, but each user or company can potentially be associated with multiple addresses (unless you add a constraint to prevent that).
Between the two options you listed, there's a third - separate tables for the associations, e.g. user_addresses (user_id FK, address_id FK) and company_addresses (company_id FK, address_id FK). This can handle any cardinality (one-to-one/one-to-many/many-to-one/many-to-many) depending on the PK (address_id, user_id/company_id or both) and possible unique constraints.
Which design is correct depends on your requirements.

Having a table with just the fields of the primary key is a conceptual error?

I'm designing a database which will store information about some artists. These artists can belongs to one or more organizations. From these organizations i just want to store their names and i'm thinking in create a table with these organizations which just have the names as primary key and nothing else. Is the fact of having a table with just the fieds of the primary key a conceptual error? In this case, i will appreciate some suggestions to solve that.
Is the fact of having a table with just the fieds of the primary key a conceptual error?
Not by itself. There are perfectly legitimate situations where all fields comprise a PK.
In this particular case, the organization name is a key, but that doesn't necessarily mean it should be primary key - you could "invent" another key that is smaller (typically integer) and easier to maintain and make it primary, like this:
The organizarion_id is called a "surrogate key", and some pros of doing that include:
Child FKs will be slimmer (since only the integer is migrated to the child, not the whole string).
You can update the organization_name without updating the organization_id, and consequently without cascading this update to children.
A small integer surrogate may be friendlier to ORMs than a more complex natural key.
Cons:
May require more JOINing.
Requires one more index, and each additional index brings overhead (even in heap-based tables, but especially in clustered tables).
As you can see, it's a matter of balance and you are the only one who has enough domain knowledge to make the right decision.
NOTE: Order of fields in organization_artist matters. Use the order shown above if you need to efficiently query for artists of a given organization and reverse it if you need organizations of a given artist. If you need both directions, you'll need another composite index on these two fields (beside the index underneath PK), but in opposite order. If you can live with only one index, consider clustering this table (if your DBMS supports it).
You want an OrganizationId, to handle the situations where the Organization name changes.
You might also have situations where different organizations seem to have the same name. How many "Museum of Modern Art"s are there? (Well, to a New Yorker, only one ;-)
Your organization table might expand over time, with columns such as shortname, address, contact person, prefered language, and so on. So, the table should look like:
create table Organizations (
OrganizationId int not null identity(1,1),
Name varchar(255),
CreatedBy varchar(255) default system_user,
CreatedAt datetime default getdate()
)
In a mature database, you would even recognize that organizations change names, merge, and sometimes split. You can handle this by adding effective dates and end dates to the records.
The standard practice for something like this would be to have 1 table for the artists, 1 table for the organizations, and 1 association table to associate the artist with 1 or more organization.
ARTIST (id, firstName, lastName)
ORGANIZATION (id, name)
ARTIST_ORGANIZATION(artist_id, org_id)
Even though the organization name may/should be unique, it's good to have a numeric id as the primary key so you can do associations. And querying the association with id is better performance than searching for a string.

Database normization 2nd form: does field should depend on FK also?

I am struggling to model a scenario and came across a question that, while normalizing table should we consider FK also as key to determine whether a field should be in same table or other table?
For example, I have Users and Teams tables (One user may ZERO or more teams considering different sports).
Owner Teams
----- --------
OwnerID ---PK TeamID ---PK
OwnerName OwnerID ---FK
TeamManager
TeamLogo
If we observe this relation, TeamManager and TeamLogo are completely dependent (functionally) on only TeamID not at all dependent UserID (am I correct in understanding this?). Should we have another table for UserID and TeamID to establish relationship?
Any suggestions would be really helpful.
This is not a home work. I am modeling for a website and improve my knowledge on normal forms to get best scalable database design.
Thank you,
... should we consider FK also as key to determine whether a field should be in same table or other table?
Being a child endpoint of a referential integrity is orthogonal to being a key (i.e. FK child may or may not be a key). The name "foreign key" only refers to the parent endpoint, which is required to be a key (in most DBMSes).
So, in your example, Teams.OwnerID does not have to be a key (and actually isn't, judging on your description).
If we observe this relation, TeamManager and TeamLogo are completely dependent (functionally) on only TeamID not at all dependent UserID (am I correct in understanding this?).
Yes, you are correct.
The Teams is in 3NF because all attributes functionally depend on key, whole key and nothing but the key (so help me Codd ;) ).
Here is why:
Nothing depends on a key subset, so this is 2NF (in fact, there is no "key subset" since key is just one attribute).
As you already noted, TeamManager and TeamLogo do not functionally depend on OwnerID, so you do not have a transitive dependency, so this is 3NF.
Should we have another table for UserID and TeamID to establish relationship?
For modeling a simple 1:N relationship like this: no.
Modeling M:N would be a different matter.
So unless there are some additional details you didn't mention, this model looks nicely normalized to me.
I I do not see a reason to have a third table for UserId and TeamId. Now if you have more infromation for TeamManager I would create a manager table. Is it one user per team? Can a user be a Manager?

Composite keys in a Multi-tenant database

I'm designing a database for pure multi-tenancy (one database, one schema) and I'd like to keep a Tenant_Id in most of my tables as a security measure to ensure that data doesn't fall into the wrong tenant's hands. It seems like this would require a composite key on every table.
Example:
Under single-tenant circumstances, I would have a single primary key:
Animal_Id (PK)
Animal_Type
Animal_Name
Under Multi-tenant circumstances, I would add another primary key for Tenant_Id:
Animal_Id (PK)
Tenant_Id (PK)
Animal_Type
Animal_Name
Does adding a Tenant_Id column to every table mean that I will need to have a composite key in every table, or is there a secure way to avoid this? Composite keys are ok, but I'd like to avoid them if I can.
If all your ids are autoincremented integers, you can add tenant_id which is not a part of the primary key and just check for it in all your queries.
However, this has several side effects which you may or may not see as drawbacks:
You can possibly link two entities from different tenants in a many-to-many link table and the FOREIGN KEY constraint won't prevent you from doing this (as it would in case tenant_id were a part of the PRIMARY KEY)
Your users can evaluate how many other tenants are there from the ids
You will have to additionally join the entity tables to the searches which could possibly be done only from many-to-many link tables (to check the tenant)
In other words, if you really don't like composite keys for entities, it is possible to design the database without them.
Unless you are repeating the other id per customer (you could have two or more animal_id = 1) there is no real reason to make it a composite key. You can just add the field. That's works for us.
Do you really need to support two different tenants having the same ANIMAL_ID value? Whatever mechanism you're using to generate what appear to be synthetic primary key values should be able to generate values that are unique across tenants. Adding a TENANT_ID column to the table would potentially make sense but it's not obvious that adding it to the primary key would be beneficial.

Resources