auto_increment index depends other table - mysql

I have two tables:
Friends :
id name
1 jhon
2 peter
Teammates:
id name
3 juan
i am looking for a way two auto increment the id of the second table (teammates) according to the first table ( Friends ).
When I add a new register to Teammates it never match with an id of Friends

I think this is not good practice. If you do so, you are introducing an implicit functional dependency between both tables outside of the declared design. If you want to it anyway, you can use a trigger to asign the value instead of making the column autoincrement.
I would suggest to have a table for all people with the real autoincrement id, then you can use several approaches:
i) Make your two actual tables take id values as foreign keys of this new table, with the corresponding integrity constraint.
ii) Simply create 2 views of the table: One for friends, other for teammates.
Table_Friends: (id, name, role)
View_Friends: Select id, name from table_Friends where role = value_for_friend_role
View_Mates: Select id, name from table_Friends where role = value_for_teammate_role

Related

Single FK referes to PK from multiple tables

I have Table A, Table B, and Table C. Table C has a column which should be a FK for a PK. The PK could be either Table A's id or Table B's id. What is the best practice to design such tables?
I am thinking of creating 2 columns in Table C, where the first one would determine either Table A or Table B, and the second one represents the id of either Table A or Table B (depending on the first column). Is it the right way to do it?
Using SQL UNION to Combine Two ResultSet with Different Joins
See: http://www.sqlfiddle.com/#!8/3519e/4
I have made an example with 3 tables:
CAR
TRUCK
DRIVER_ASSIGNED
You can create one query to join A with C, another to join B with C, and join the two result sets using UNION. For example:
(select * from `A`,
`C`
where `A`.ID = `C`.`ID` and
`C`.`Type` like 'A')
UNION
(select * from `B`,
`C`
where `B`.ID = `C`.`ID` and
`C`.`Type` like 'B')
In Relation to Classes and Sub-Classes
It seems to be that TABLE A and TABLE B are sub-types of another type/class. So, e.g. TABLE A may be cars, and TABLE B, may be trucks, but they extend vehicles.
In this case I think you need a fourth table, TABLE PARENT, that will combine the common fields of both A and B. C will use the primary key of TABLE PARENT as the foreign K.
TABLE A and B will contain both as foreign keys but maybe also as primary keys the primary key of table PARENT.
So, using my analogy with vehicles let us assume:
TABLE A = CARS
TABLE B = TRUCKS
TABLE C = ASSIGNED_DRIVERS
TABLE PARENT = VEHICLES
TABLE VEHICLES - PARENT of A and B
-------------
ID (PK)
HORSE POWER
LICENSE PLATE
etc...
TABLE CARS -
-------------
ID (PK)
VEHICLE_ID (FK linking to VEHICLES.ID)
NUMBER_SEATS
etc...
TABLE TRUCKS -
-------------
ID (PK)
VEHICLE_ID (FK linking to VEHICLES.ID)
HIGHT (meters)
MAXIMUM_STORAGE_WEIGHT
etc...
TABLE DRIVERS_ID -
-------------
VEHICLE_ID (FK linking to VEHICLES.ID)
DRIVER_OD
START_DATE
END_DATE
etc...
So, the following method would save you from this problem and also be more semantically correct.
You can also check online documentation such as:
http://www.dssbooks.com/web/Files/LookInside/Web-DSS-Chapter-03.pdf (page 55) to see the theory between classes and subclasses.
I am thinking of creating 2 columns in Table C, where the first one would determine either Table A or Table B, and the second one represents the id of either Table A or Table B (depending on the first column). Is it the right way to do it?
No. You would be preventing the DBMS from enforcing the foreign key. You'd have to enforce the FK through triggers or the application code, which is more prone to errors and potentially less performant.
Either make two FK fields (one for Table A, other for Table B) and use a CHECK1 to ensure only one of them is not NULL, or use inheritance.
More info in this post.
1 Unfortunately, MySQL parses but doesn't enforce CHECK constraints, so you'll need to use a trigger instead. This limitation doesn't exist in other DBMSes.

How to structure my Users Database?

I have a website that allows users to be different types. Each of these types can do specific things. I am asking if I should set up 1 table for ALL my users and store the types in an enum, or should I make different tables for each type. Now, if the only thing different was the type it would be easy for me to choose only using one table. However, here's a scenario.
The 4 users are A, B, C, D.
User A has data for:
name
email
User B has data for:
name
email
phone
User C has data for:
name
email
phone
about
User D has data for:
name
email
phone
about
address
If I were to create a single table, should I just leave different fields null for the different users? Or should I create a whole separate table for each user?
Much better if you could create a single table for all of them. Though some fileds are nullable. And add an extra column (enum) for each type of users. If you keep your current design, you will have to use some joins and unions for the records. (which adds extra overhead on the server)
CREATE TABLE users
(
ID INT,
name VARCHAR(50),
email VARCHAR(50),
phone VARCHAR(50),
about VARCHAR(50),
address VARCHAR(50),
userType ENUM() -- put types of user here
)
Another suggested design is to create two tables, one for user and the other one is for the types. The main advantage here is whenever you have another type of user, you don't have to alter the table but by adding only extra record on the user type table which will then be referenced by the users table.
CREATE TABLE UserType
(
ID INT PRIMARY KEY,
name VARCHAR(50)
)
CREATE TABLE users
(
ID INT,
name VARCHAR(50),
email VARCHAR(50),
phone VARCHAR(50),
about VARCHAR(50),
address VARCHAR(50),
TypeID INT,
CONSTRAINT rf_fk FOREIGN KEY (TypeID) REFERENCES UserType(ID)
)
Basic database design principals suggest one table for the common elements and additional tables, JOINed back to the base table, for the attributes that are unique to each type of user.
Your example suggests one and only one additional field per user-type in a straightforward inheritance hierarchy. Is that really what the data looks like, or did you simply for the example? If that's a true representation of your requirements, I might be tempted (for expedience) to use a single table. But if the real requirements are more complex, I'd bite the bullet and do it "correctly".
Try creating four tables:
Table 1: Name, email
Table 2: Name, phone
Table 3: Name, about
Table 4: Name, address
Name is your primary key on all four tables. There are no nulls in the database. You're not storing an enumerated type but derive the type from table joins:
To find all User A select all records in table 1 not in table 2
To find all User B select all records in table 2 not in table 3
To find all User C select all records in table 3 not in table 4
To find all User D select all records in table 4
You should not create tables for different people because this will lead to a bloated database. It's best to create a single table with all the fields you need. If you don't use the field, pass in null values.
I would suggest that you use 1 single table with nullable fields. And a table of something like roles.

creating a new mysql table with a primary auto incrementing id that is linked to another table?

I want two tables to share a primary auto incrementing id, is this possible? how do i do this? is their anything i need to consider?
the reasons i am doing this, is because it is a better solution than adding groups column to the users table, and also better than creating a completly seperate groups table, because if they share a primary key, i can use the existing posts table for both groups and users. instead of having to create a two distinct posts tables, (group_posts table for group posts. and a user_posts table for user posts.)
existing users table is
id(primary, ai)
username
password
email
my groups table that i want to link to my users table with a shared ai primary key
id(primary, ai, linked to users table id)
group_name
created_by
creation_date
etc.
You should make you schema clearer by doing the following:
Create a table (e.g. people)
id, primary key, auto-increment
type, tells you if it's a user or a group
Make users and groups primary keys foreign keys on people
Insert records in people
Obtain the ID that was assigned using LAST_INSERT_ID()
Insert in users or groups appropriately, using the ID obtained above
Then you'd reference "people", and not "users" or "groups" in your posts table and so on.
Conceptually, thinking of it in an OO way, it means users and groups both extend people.

having trouble with foreign key queries

I'm new to SQL and I'm having a hard time figuring out how to execute queries with foreign keys on MySQL Workbench.
In my example, I have three tables: people, places, and people_places.
In people, the primary key is people_id and there's a column called name with someone's name.
In places, the primary key is places_id and there's a column called placename with the name of a place.
People_places is a junction table with three columns: idpeople_places (primary key), people_id (foreign key), and places_id (foreign key). So this table relates a person to a place using their numerical IDs from the other two tables.
Say I want the names of everyone associated with place #3. So the people_places table has those associations by number, and the people table relates those numbers back to the actual names I want.
How would I execute that query?
Try this to find all the people names who are associated with place id 3.
SELECT p.name
FROM people as p
INNER JOIN people_places as pp on pp.people_id = p.people_id
WHERE pp.places_id = 3
OK, so you need to "stitch" all three tables together, yeah?
Something like this:
select people.name
from people -- 1. I like to start with the table(s) that I want data from, and
, people_places -- 2. then the "joining" table(s), and
, places -- 3. finally the table(s) used "just" for filtering.
where people.people_id = people_places.people_id -- join table 1 to table 2
and people_places.place_id = places.place_id -- join table 2 to table 3
and places.name = "BERMUDA" -- restrict rows in table 3
I'm sure you can do the rest.
Cheers. Keith.

How to migrate a recursive table?

Let's say I have a table, category, which has 3 columns, id, parent_id and name.
I have several tables like this, and I want to consolidate them into one. At present, their IDs will clash (not unique across DBs) so I need to re-ID them. If I make id an auto_increment I can copy all the other columns over just fine, but then parent_id won't link up properly anymore. Is there some magical way I can get the parent_id to point to the correct new ID?
Looking for something like
INSERT INTO newtable (parent_id, name) SELECT ???, name FROM oldtable
How about
Generate a new table with a column containing the name of the old table and old id (oldid, oldtablename) along with a new ID
Add a new column 'newparentid'
Update each row's newparentid to be (SELECT newid FROM newtable nt WHERE oldtablename = row.oldtablename and nt.oldid = row.parent_id)
I imagine you could add an old_id column so that you'll still have the original id and you can run successive updates to the table to modify all the parent_ids to point to the new auto_inc ids. You would obviously have to kill any foreign keys requirements on the table first and reinstitute them after all the changes were made – Patrick