Best way to create a multi relational database in my scenario - mysql

I'm having trouble to develop my database model.
I have the tables TOUR and TRIP (both with GUID primary key) and both have some children tables in common. Like DETAIL, COMMENT, MEDIA, PRICE and like that.
I'm thinking in create in those children tables some "ParentId" column to link with TOUR or TRIP, but I need to know which parent table is. In this way I should to create a column "ParentType" where 1 is TOUR and 2 is TRIP or maybe create a TourDetail and a TripDetail to link each one with other table?
I'm looking for the best practice to do that.

In terms of design, the SQL convention is that each relationship should have its own column in the referencing table. That's the concept if foreign key columns.
So you need to create two columns in each child table (DETAIL, COMMENT, MEDIA, PRICE), like TOUR_ID and TRIP_ID that will contain the primary key of the correspondig records in, respectively, tables TOUR and TRIP. Of course if a children refers to only one parent and not the other, only one column is necessary.
This will then allow you to build proper JOIN queries like :
SELECT
...
FROM TRIP
JOIN DETAIL on DETAIL.TRIP_ID = TRIP.ID
...
WHERE
...

Related

how to make a relationship table between 3 table (2 to 1) in SQL

lets say we have 3 table in our database
tables:
table books:
book_id
book_title
...
table magazines:
magazine_id
magazine_title
...
and genres:
genre_id:
genre_name
and now we say want to know what book has what genre and what magazine has what genre, this is the way i know for two table
relation tables:
table book_genres:
genre_id
book_id
table magazine_genre:
genre_id
magazine_id
in this way we have to create several separate table for joining the books, magazine and maybe more tables. and i been told that always have 2 id column in join tables.
but i'm wondering about if i could do something like this
the table that not working!
table title_genres:
genre_id
book_id
magazine_id
...
this is more simple but i get an error when i insert a book genres that says magazine_id can't be empty NULL because its primary key.
its gonna be save me for creating a lot of tables. like if i decide to have a category table then i have to join books and magazine separately.
and my question: is the 2 column thing is a good practice or there is a better way for this?
You use bridge tables to represent m:n relationships. If a book can have many genres and a magazine can have many genres, then you need bridge tables like the book_genres table you are showing.
And if books are very different from magazines in your database, then yes, have separate tables for books and magazines.
This leads to two bridge tables, just as you describe and I see nothing wrong with this.
Your idea to have one bridge table is generally possible, but doesn't solve any problem.
But well, let's see how we would construct such a multi bridge table. First of all you'll want a check constraint ensuring that always exactly one of the columns book_id and magazine_id is filled. Then you want a unique constraint on COALESCE(book_id, magazine_id), genre_id. This would usually be done with a function index, which MySQL doesn't support as far as I know. I suppose though, that you could create a generated column which you can index in MySQL.
And then you want to read the relations as quick as possible. With a bridge table like book_genres you have one row per book and genre and an index to get the relation as quick as possible. With a multi bridge table like title_genres you don't. You have one table containing relations you are interested in and others you are not interested in. You'd want a partial index like
create unique index idx on title_genres (book_id, genre_id) where book_id is not null;
but MySQL doesn't support partial indexes. You could
create unique index idx on title_genres (book_id, genre_id);
which leads to a larger index, but serves the purpose. You'd do the same with
create unique index idx2 on title_genres (magazine_id, genre_id);
And now, with all this work, what have you gained? Your database has become way more complicated than with the simple book_genres and magazine_genres tables. Keep it simple. Use these two tables instead of the multi bridge monster :-)
You can absolutely store the records this way if you have a category field that has information such as (books, magazines etc). So, in other words your table is vertically partitioned by category field but logically it’s a single table.
Only drawback I can see is if this table grows fast then query performance would be a problem because (a) the table will be huge so it will consume more memory even if you are only looking for specific categories and not all of them (b) you always have to use inline sub query since your category filter have to applied every time for every join and when you use inline queries for joins the database would not be able to make use of indexes will be affect the performance of the queries.
Note : You would not be able to store the records in any other way. For example even if a magazine and a book have same genre you have to have them in separate rows and not the same row because if you do that your model will get into other kind of troubles.

MySQL : One to One Relationship Tables Merging

I am trying to simplify an application's database. In that database I have two tables let's say Patient and MedicalRecord. I know that two tables are said to be in One-to-One relationship iff that any given row from Table-A can have at most one row ine Table-B(It means there can be zero matchings).
But in my case, it is not at most, it is exactly. i.e., Every row in Patient should have exactly one row in MedicalRecord(no patient exist without a medical record).
Patient table has all personal details of the patient with his id as PK.
MedicalRecord talbe has details like his blood-group, haemoglobin, bp etc with his id as both PK and FK to the Patient.
My Question is, can I merge those two tables and create one table like,
PatientDetails : personal_details and blood-group, haemoglobin, bp etc
"bp" = "Blood pressure"? Then you must not combine the tables. Instead, it is 1:many -- each patient can have many sets of readings. It is very important to record and plot trends in the readings.
Put only truly constant values in the Patient -- name, birthdate (not age; compute that), sex, race (some races are more prone to certain diseases than others), not height/weight. Etc.
Sure, a patient may have a name change (marriage, legal action, etc), but that is an exception that does not affect the schema design, except to force you to use patient_id, not patient_name as a unique key.
Every patient must have a MedicalRecord? That is "business logic"; test it in the application; do not depend (in this case) on anything in the Database.
Both tables would have patient_id. Patients would have it as the PRIMARY KEY; MedicalRecord would haveINDEXed`. That's all it takes to have 1:many.
In situations where the tables are really 1:1 (optionally 1:0/1), I do recommend merging the table. (There are exceptions.)
If two tables have the same set of subrow values for a shared set of columns that is a superkey in both (SQL PRIMARY KEY or UNIQUE) then you can replace the two tables by their natural join. ("Natural join" is probably what you mean by "merge" but that is not a defined technical term.) Each original table will equal the projection of the join on that original's columns.
(1:1 means total on both sides, it does not mean 1:0-or-1, although most writing about cardinalities is sloppy & unclear.)

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.

fastest way to query a field that has more than one possible matching value

I have 2 tables.
First table is called professions, and those are indexed by ID. So each profession now has a unique ID associated with it.
My second table is called contacts, and in there I have a profession field that right now only hold the ID that a certain profession is associated with.
My problem is that what if I have a contact that has more than one profession associated with it.
What would be the best way to query the table and ways to store the professions of a contact. I didn't want to do is create a field to just store a 0 or 1 int for each profession I have. The reason is because I want to dynamically grow the professions table and have the numbers reflect any dynamic changes on my site when I query.
You have a many-to-many relationship. To implement that in MySQL you should use a linking table. So professions and contacts should have an id in each table, but no foreign keys, and you create a new table called profession_contact_links or something, containing its own id, and profession_id and contact_id, which are both foreign keys to the respective tables. Then you can have many contacts linked with each profession, and many professions linked with each contact. To connect the two main tables together in a select you will need two joins, and what they are will depend on what exactly you want to select.
The standard solution to this modelling issue is called a link table.
Basically it is a table that contains the ids of the two tables that are linked, so you would have a link table with to columns and a primary key that is both of those columns:
(profession_id, contact_id)
or the other order... doesn't matter that much, but the order can affect performance, the key you will be searching on most often is the one you want first.
You then use either SELECT ... IN (...) or SELECT ... JOIN ... to query the data that you are after.
Depending on what you want and how you want to find it, i'd suggest rlike or in
SELECT ... FROM <table> WHERE <column name> RLIKE "^id1|id2|id3$"
This will find any cell that contains any of those three terms
or use
SELECT ... FROM <table> Where <column name> IN ('id1','id2','id3')
this will find any cell that is equals to one of those three.

Foreign keys from different tables

I have a problem in designing a database for a "business". I have some database for different types of products( for example car parts, groceries and some other stuff). Now if I want to make a business, meaning that I want to sell these items, I am thinking that I am going to need a table like Products which will contain a product foreign key, a stock and a price. My question is how can I use foreign keys in my Products table from my existing tables? I was thinking of using a combination of foreign keys (i.e in the Products table I would have a column for each product type), but I don't think it's such a good idea. What if I would want to expand my business to other types of products? Any ideas?
Consider inheritance:
You can use a table products which will be supertype of the products you have and refer to this table though the foreign key. If you want more info about how to implement inheritance click here