Can A Foreign Key Be Used More than Once? - mysql

Apologies for the newbie question.
The primary key of a table, such as Holiday, would be something like Holiday_ID. Holiday reference a get-away ticket that you can buy to go on a type of holiday, based on the ticket you buy.
Suppose I used Holiday_ID in a composite entity with Customer_ID to identify an instance of Holiday associated with customer, for whatever purpose.
However, suppose I also want to keep track of other information related to this instace: how much has the customer paid for the ticket, how much has the customer yet to pay for the ticket
I have two options:
a) I can create another composite entity. However, I am not sure if I can do that because I am not sure if you can use a particualr foreign key more than once
b) I can create a composite/associate entity, however, I am not sure if you can create a composite entity with more than two foreign keys?

To answer the technical parts of your question, once you create a composite unique or primary key, ONLY ONE record in the table can have the same values in the set of fields defined in that key. SO, no, you cannot reuse the holidayId key WITH THE SAME customer. You can use it with another, different customer if you wish.
Second, there is no limit to the number of attributes that can be included in a Unique or primary key. If you need, and if it's appropriate and conforms to the rules of normalization, the key can include all the attributes of the table.
Third, to answer your question below, Any column, or set of columns in a table can be defined as a Foreign Key, as long as it is also the primary key or unique key of some table in the database. And there can be any number of FKs defined in a table, they can even overlap. (you can have HolidayId as a FK, and also have HolidayID and CustomerId as a composite FK) the only restriction is that the FK must reference a Primary or Unique Key of some table in the database.(It can also be the same table the FK is in as well, as when you add a supervisorId to an employee Table that is a FK to the EMployeeId of the same employee table)
This example illustrates one of the problems of using surrogate keys without also using a natural key. to wit, what, exactly is a "Holiday"? Is Christmas 2016 the same "Holiday" as Christmas 2015? Is Christmas in Aruba the same holiday as Christmas in Hawaii?
and then, about the composite table to identify associations of customer with Holiday, is it the same association if the customer goes to Aruba on Christmas the next year, or a different instance? What does the row in the table represent if the customer wants 5 tickets?
The first thing that should be done in database design is a logical design which defines, as clearly and unambiguously as possible, in business terms, the meanings of the entities for each table in the database.

Related

Products and Bill of Materials

I have a products table link to a bill of materials table. See diagram
Each product can have more than one formula. For example:
Currently ProdIDNeed and ProdIDNeeded are my composite primary key, both fields also link as foreign keys to ProdID (Products). The only way I can think of preventing a key violation is to create a Formula field and have a 3 field composite primary key (ProdIDNeed, ProdIDNeeded, FormulaNumber).
However, I have to link the product_billmaterials table to a workorders table (bascially an order to make the product according to formula). Linking three fields to another table is a pain.
I guess I could also create a surrogate key on the product_billmaterials table which I am not too crazy about either.
Is there any other way I can organize this or must I choose one of the options I have thought of?

Database Relationships - One-to-One that also has One-to-Many

Let's say you have one cook that has one restaurant, and vice versa. So with a one-to-one relationship, you would have the primary key id in the cooks table and cook_id as the primary and foreign key in the restaurants table.
So how would you represent a relationship of one-to-many between the restaurant and its customers? Since the restaurant does not have its own ID, would the customers table have its own id and then contain foreign keys of cook_id?
Edit: I've thought of a better and more realistic example. Let's say you have a work order that only ever has one quote. You'll have the work order's id in the quotes table, since it's 1-to-1. Being a quote, it's bound to change, and that same particular quote gets revised. If you wanted to record the revisions made to a quote (or some sort of history log), you'd want something like a quote_revisions table. In this case, a work order only ever has one quote, and a quote can have many quote revisions. With what IDs do you link the quotes and quotes_revisions table?
Since you have a one-to-one relationship, the cook's id is the restaurant's id too. You can relate customers to restaurants by associating customer keys with cook/restaurant keys in a table (customers or another table). The one-to-many cardinality is enforced by placing a unique constraint on the customer's key so that they can't be associated with more than one restaurant/cook.
Using the Work_order example:
Work_order would have a PK of, say, wo_id, and it might be AUTO_INCREMENT.
Quotes would have a PK with the same wo_id, but not AUTO_INCREMENT.
Quote_revisions would have an INDEX(wo_id), but some other column(s) for the PK.
Work_order and Quotes are "1:1", as provided by wo_id.
Quotes and Quote_revisions are "1:N"; wo_id in both tables provides that relationship.
It is rarely useful to have 1:1, but your example might be a good use case. (One table is relatively large and static, the other is relatively small and frequently changed.)
I would instead have a restaurant_id field as the primary key in the restaurant table, along with cook_id as a foreign key. Yes, this structure would support a one-to-many relationship just as well as a one-to-one relationship, but I believe each entity should nevertheless have its own ID. If you like, you can put a unique constraint on the foreign key, to ensure that the relationship does remain one-to-one. Or you could simply have a single restaurant table that includes fields with information about its head chef.

Is it necessary to bring the primary key of non repeating table while normalizing the database from UNF to 1NF

My UNF is
database(
manager_id,
manager_name,
{supplier_id,
supplier_name,
{order_id,
order_quantity}}
{purchase_id,
purchase_date}
Here manager_name, supplier_id, order_id and purchase_id are primary key.
During normalization there will be 1 table called purchase. Is it necessary to make manager_name as a foreign key?
How can I normalize these database?
This is a part of my college project on database. Normalization is really confusing.
First consider splitting things out by things that naturally go together. In this case you have manager information, supplier information, order information and purchase information. I personally would want to know the difference between an order and a purchase because that is not clear to me.
So you have at least four tables for those separate pieces of information (although depending on the other fields you might need, suppliers and managers could be in the same table with an additional field such as person_type to distinguish them, in this case you would want a lookup table to grab the valid person type values from). Then you need to see how these things relate to each other. Are they in a one to one relationship or a one-to many or a many to many relationship? In a one-to one relationship, you need the FK to also have a unique constraint of index to maintain the uniqueness. In a many to many you will need an additional junction table that contains both ids.
Otherwise in the simplest case the child table of purchase would have FKs to the manager, supplier. and order tables.
Manager name should under no circumstances be a primary key. Many people have the same name. Use Manager ID as the key because it is unique where name is not. In general I prefer to separate out the names into First, middle and last so that you can sort on last name easily. However in some cultures this doesn't work so well.

Normalization of data for database?

Here is the data I have to normalize:
//
1NF
Customer ID [First Name (PK), Last Name (PK), Phone, Address, Town, Postcode, Email]
Booking [Date (PK), Room (PK), Type, Occupants, Nights, Arrival Time]
ExtraID [Item Name, Item Cost, Date (FK), Room (FK)]
//
First Name + Last Name = Composite Key
Date + Room = Composite Key
//
Is this ok?
Also to go into 2NF I have to identify partial dependencies. As far as I see Phone, Address, Town, Postcode and email requires both parts of the composite key?
So is this in 2NF already?
Thank you.
It's generally a good idea to use synthetic keys. This has to do with people, especially---none of the natural keys are truly fit for the primary key purpose (we might go into biometrics here but this would be a bit off topic).
So, there would need to be a table of customers with its own customers_pk primary key which could be either a sequence in the RDBMS or, say, GUID (http://en.wikipedia.org/wiki/Globally_unique_identifier).
There should be a historical table for rooms---the rates tend to change, as well as other room's characteristics. We could define a room to be unique physical object and also decide on whether a room stays the same after remodelling (there are pros and contras to that, it would depend on the business standpoint).
I would create a separate dictionary for the extras (we could use receipt IDs in there and CDR's references) and then link the extras with the bookings via a table with it's own primary key, foreign key to booking's primary key and the foreign key to extra's primary key.
Now, bookings' table should have it's own primary key, then customer's key, rooms' key, dates (they could be date type or we could create a separate time dimension where we could list various useful information such as whether it's high season or if there are some local events), number of occupants, sum of extras charges (well, might be not the best of all ideas) and the grant total.
You could use a separate sequence for each table's keys or just one for all of them---the latter is a bit more elegant.

How to query MySQL by one of the field's subvalue?

Let's assume there is a table, with theese rows:
-personID,
-personName,
-personInterests
There is also another table, which stores the interests:
-interestID
-interestName
One person can have multiple interests, so I put the serialize()-d or JSON representation of the interest array into the interest field. This is not a String, like "reading", buth rather an index of the interests table, which stores the possible interests. Something like multiple foreign keys in one field.
The best way would be to use foreign keys, but it is not possible to achieve multiple references in one field...
How do I run such a query, without REGEX or splitting the field's content by software? If putting indexes to one field is not the way to go, then how is it possible, to achieve a structure like this?
Storing multiple indexes or any references in one field is strictly not advised.
You have to create something that I call "rendezvous" table.
In your case it has:
- ID
- UserID (foreign key)
- InterestID (foreign key)
Every single person can have multiple interests, so when a person adds a new interest to himself, you just add a new row into this table, that will have a reference to the person and the desired interest with a foreign key NOT NULL.
On large-scale projects when there are too many variations available, it is advised, to not to give an ID row to this table, but rather set the two foreign keys also primary keys, so the duplication will be impossible and the table-index will be smaller, as well as in case of lookup, it will consume less from the expensive computing power.
So the best solution is this:
- UserID (foreign key AND primary key)
- InterestID (foreign key AND primary key)
I believe the only way you can implement this is to create a third table, which will actually get updated by a trigger (Similar to what Gabor Dani advised)
Table1
-personID,
-personName,
-personInterests
Table2
-interestID
-interestName
Table3
-personInterestID (AutoIncrement Field)
-personID
-interestID
Then you need to write a trigger which will do this a stored procedure may be needed because you will need to loop through all the values in the field.