Inheritance in MySql - mysql

I need to create a huge table called worker (id_worker is the primary key) and lots of other columns like name, date_of_birth, etc.
I also need to create several other tables that inherit this one (all the different kinds of workers from the company). They all have the attributes from worker (name, date_of_birth) and also the same primary key (id_worker).
I read that I cannot do this in MySQL because it does not support inheritance. How do I do it then?

CREATE TABLE workers(id INT(11) NOT NULL, name VARCHAR(64), date_of_birth DATE);
CREATE TABLE worker_type(id INT(11) NOT NULL, name VARCHAR(64));
CREATE TABLE workers_types(worker_id INT(11) NOT NULL, woker_type_id INT(11) NOT NULL);
SELECT workers.name, worker_type.name FROM workers
LEFT JOIN workers_types ON workers_types.worker_id = workers.id
LEFT JOIN worker_type ON worker_type.id = workers_types.worker_type_id;
Sorry not proofed and bad naming...

Related

MySQL Procedure to insert data to a table that use auto_increment, get the PK auto_increment generated and insert it into a bridgetable?

I´m creating a restApi with PHP over the courses I have studied. When it comes to the database I´m not sure whats the best practise for this problem ->
I have data over the languages each course had, to normalize data I have languages in a separate table and a bridge to connect them.
So one table for Courses, one for Languages and one bridge table to connect them.
CREATE TABLE `Courses`
(`Course_ID` INT(11),
`Education_ID` INT(11),
`CourseName` VARCHAR(100) NOT NULL,
`Points` VARCHAR (5),
`Grade` VARCHAR(3),
PRIMARY KEY (`Course_ID`)
);
CREATE TABLE `Language` (
`Language_ID` INT(11),
`Language` VARCHAR(100) NOT NULL,
`Img_url` VARCHAR (200),
PRIMARY KEY (`Language_ID`)
);
CREATE TABLE `Bridge_language` (
`Course_ID` INT(11) NOT NULL,
`Language_ID` INT(11) NOT NULL,
KEY `PKFK` (`Course_ID`, `Language_ID`)
);
ALTER TABLE Courses MODIFY Course_ID INTEGER AUTO_INCREMENT;
ALTER TABLE Language MODIFY Language_ID INTEGER AUTO_INCREMENT;
When adding a new course, in the SQL I know the id of the languages, (i will have a function in the admin page where you add new languages) then when you create a new course you just click add languages and the id for the language is added.
But what I don't have is the ID for the course which is created with auto_increment. Is there a smart way you with a function/procedure in SQL, can grab the id that auto_increment has generated and use it to add that into the bridge table?
Or do I need to make a query to the database and grab the latest ID and add one and send that into the bridge table?
In MySQL, you can use last_insert_id() to retrieve the auto-generated id of the last insert query that you executed. You don't give much details about your code, but the logic is like:
insert into course (education_id, coursename, points, grade)
values (?, ?, ?, ?);
insert into bridge_language (course_id, language_id)
values (last_insert_id(), ?);

modeling issue with field with 4 values (1 or more)

lets say I have an account object in my application, which currently represented as:
CREATE TABLE Account (
accountId int NOT NULL AUTO_INCREMENT,
name varchar(255) NOT NULL,
PRIMARY KEY (accountId)
);
Now, Account object need to also have Solution field...and Status have 4 different possible values:
Solution1, Solution2, Solution3, Solution4
What would be the right way to represent it in the database?
Account can have few statuses, and status can have few accounts...
So at first I thought create in the db table of Solutions and than have another table to hold the relationship, but its seems too complicated for a field that have only 4 possible values...
Create a junction table to represent the relationships between accounts and solutions:
CREATE TABLE account_solution (
accountId int NOT NULL,
solutionId int NOT NULL
PRIMARY KEY (accountId, solutionId)
)
For your solution table, since there are only 4 values, you might be able to take advantage of MySQL's enum type, e.g.
CREATE TABLE solution
solutionId int NOT NULL PRIMARY KEY,
status ENUM('Solution1', 'Solution2', 'Solution3', 'Solution4')
);
You can use set Mysql SET type
CREATE TABLE Account (
accountId int NOT NULL AUTO_INCREMENT,
name varchar(255) NOT NULL,
status set('Solution1','Solution2','Solution3','Solution4') NOT NULL,
PRIMARY KEY (accountId)
);
And if you want to select a specific status
SELECT *
FROM `Account`
WHERE FIND_IN_SET( 'Solution2', `status` ) >0

How to create a MySQL database for users data

I would like to save user data in my database.
There is common data about the user account (nickname, password, etc.) but also data like firstname, name, age, location, ...
How can I manage my data base? Should I create different tables? One containing common user data and another containing all the other data?
This is a design choice, and it basically depends on how much information you usually need, and how many extra fields you have.
Option 1: Keep them in the same table, if its not too much or you usually need all the data.
Option 2: Create a User Profile table, that contains the user data that its related to the person and not the account.
create one single table.
CREATE TABLE `admin`
(
`User_Name` varchar(60) NOT NULL,
`Password` varchar(60) NOT NULL,
'firstname' varchar(60) not null,
'Age' int(11) Not null,
'Location' varchar(50) NOT NULL,
PRIMARY KEY (`User_Name`)
)
ENGINE=InnoDB DEFAULT CHARSET=latin1;
Create 2 tables:
1. userProfile
create table userProfile(
UserID int primary key auto_increment(1,1),
firstname varchar(50),
age int(11),
location varchar(50));
2.userAccounts:
create table userAccounts(
ID int primary key auto_increment(1,1),
UserID int(11),
UserName varchar(50),
Password varchar(50));
there is a relation between Table1(UserID) and Table2(UserID).

MySQL table linking 1:n

So first up I'm not sure if this is a double post or not because I don't know how the exact approach or feature is called and if it even exist.
I know that MySQL has a feature called joins
My plan is to link two MySQL tables in relation 1:n one is t_user the other one t_event.
t_user:
CREATE TABLE t_user (
uId INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(25) NOT NULL,
...
)
t_event:
CREATE TABLE t_event (
eId INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(40) NOT NULL,
date DATETIME NOT NULL,
members ???,
...
)
I want the users to "subscribe" to the events and get stored in the members column as a list (?). This would be no problem if only one user would subscribe to one event. But I have no idea how to setup the t_event table to store more than one user and how to query for all the events a user has "subscribed" for.
This is usually done via third table:
CREATE TABLE t_eventsusers (
eId INT(6),
uId INT(6)
)

Best way with relation tables

I have a question about tables and relations tables ...
Actually, I have these 3 tables
CREATE TABLE USER (
ID int(11) NOT NULL AUTO_INCREMENT,
NAME varchar(14) DEFAULT NULL
);
CREATE TABLE COUNTRY (
ID int(11) NOT NULL AUTO_INCREMENT,
COUNTRY_NAME varchar(14) DEFAULT NULL
);
CREATE TABLE USER_COUNTRY_REL (
ID int(11) NOT NULL AUTO_INCREMENT,
ID_USER int(11) NOT NULL,
ID_COUNTRY int(11) NOT NULL,
);
Ok, so now, 1 user can have one or more country, so, several entries in the table USER_COUNTRY_REL for ONE user.
But, my table USER contains almost 130.000 entries ...
Even for 1 country by user, it's almost 10Mo for the USER_COUNTRY_REL table.
And I have several related tables in this style ...
My question is, is it the fastest, better way to do?
This would not be better to put directly in the USER table, COUNTRY field that contains the different ID (like this: "2, 6, ...")?
Thanks guys ;)
The way you have it is the most optimal as far as time constraints go. Sure, it takes up more space, but that's part of space-time tradeoff - If you want to be faster, you use more space; if you want to use less space, it will run slower (on average).
Also, think of the future. Right now, you're probably selecting the countries for each user, but just wait. Thanks to the magic of scope creep, your application will one day need to select all the users in a given country, at which point scanning each user's "COUNTRY" field to find matches will be incredibly slow, as opposed to just going backwards through the USER_COUNTRY_REL table like you could do now.
In general, for a 1-to-1 or 1-to-many correlation, you can link by foreign key. For a many-to-many correlation, you want to have a relation table in between the two. This scenario is a many-to-many relationship, as each user has multiple countries, and each country has multiple users.
Why not try like this: Create table country first
CREATE TABLE COUNTRY (
CID int(11) NOT NULL AUTO_INCREMENT,
COUNTRY_NAME varchar(14) DEFAULT NULL
);
Then the table user:
CREATE TABLE USER (
ID int(11) NOT NULL AUTO_INCREMENT,
NAME varchar(14) DEFAULT NULL,
CID Foreign Key References CID inCountry
);
just Create a Foreign Key relation between them.
If you try to put this as explicit relation , there will lot of redundancy data.
This is the better approach. You can also make that Foreign Key as index . So that the databse retrieval becomes fast during search operations.
hope this helps..
Note : Not sure about the exact syntax of the foreign key