Generate and Join UUID keys of two tables (SQL) - sql

I'm building a simple database in MySQLWorkbench with two tables: Study (1) and Series (2). In the future, we will import data from a CSV file into these tables.
Study should generate a new UUID as PRIMARY KEY (PK) named ID for every new row.
Subsequently, Series should generate a new UUID as PK named ID for every new row.
Lastly, Series should generate a Foreign Key (FK) StudyID, with the same UUID's as the Study table column ID, so that these two tables can be joined on UUID for the ascending rows.
I found topics on stack with a somewhat similar question, but this didn't solve my problem:
How to insert the same UUID in two rows of two different tables
Best practices on primary key, auto-increment, and UUID in RDBMs and SQL databases
Could anyone give me a push in the right direction?
My code:
CREATE SCHEMA IF NOT EXISTS `analog_db` DEFAULT CHARACTER SET utf8 ;
USE `analog_db` ;
CREATE TABLE Study (`ID` VARCHAR(36) DEFAULT (UUID()),
`Number` VARCHAR(36) NOT NULL,
PRIMARY KEY (`ID`) );
CREATE TABLE Series (`ID` VARCHAR(36) DEFAULT (UUID()),
`Number` VARCHAR(36) NOT NULL,
`StudyID` VARCHAR(36) DEFAULT (UUID()),
PRIMARY KEY (`ID`),
KEY `FK_StudyID` (`StudyID`),
CONSTRAINT `FK_StudyID` FOREIGN KEY (`StudyID`) REFERENCES `Study` (`ID`) ON DELETE NO ACTION ON UPDATE NO ACTION );

Related

Sql creating table consisting of keys from other tables

this is probably a simple question but I am quite new to SQL and databases, so I have been following this site: https://www.postgresqltutorial.com/postgresql-foreign-key/ to try and create a table that consist of primary keys from other tables.
Here I have the structure of the database in an excel overview. With colors showing the relations. i am having problems with the One-To-Many tables. As I get the same error every time "ERROR: column "id" referenced in foreign key constraint does not exist
SQL state: 42703".
The SQL query:
DROP TABLE IF EXISTS ingredient_to_unit_relations;
DROP TABLE IF EXISTS ingrediens;
CREATE TABLE ingrediens (
id serial,
name_of_ingredient varchar(255),
price_per_unit int,
PRIMARY KEY (id)
);
CREATE TABLE ingredient_to_unit_relations (
ingredient_relation_id int GENERATED ALWAYS AS IDENTITY,
PRIMARY KEY (ingredient_relation_id),
constraint Fk_ingredient_id
FOREIGN KEY (id)
REFERENCES ingrediens (id)
);
You need to define the column in order to declare it as a foreign key:
CREATE TABLE ingredient_to_unit_relations (
ingredient_relation_id int GENERATED ALWAYS AS IDENTITY,
ingredient_id int,
PRIMARY KEY (ingredient_relation_id),
constraint Fk_ingredient_id FOREIGN KEY (ingredient_id) REFERENCES ingrediens (id)
);
I might recommend some somewhat different naming conventions (I changed the name id in the table above):
CREATE TABLE ingredients (
ingredient_id int GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
name varchar(255),
price_per_unit int
);
CREATE TABLE ingredient_to_unit_relations (
ingredient_relation_id int GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
ingredient_id int,
CONSTRAINT Fk_ingredient_id FOREIGN KEY (ingredient_id) REFERENCES ingredients (ingredient_id)
);
Notes:
I am a fan of naming primary keys after the table they are in. That way, foreign keys and primary keys usually have the same name (and you can use using if you choose).
Avoid SERIAL. GENERATED ALWAYS AS IDENTITY is now recommended.
You can inline primary key constraints (as well as other constraints).
There is not generally a need to repeat the table name in a column (other than the primary key). So, name instead of name_of_ingredient.
Using int for a monetary column is suspicious. It doesn't allow smaller units. That might work for some currencies but in general I would expect a numeric/decimal type.

Storing foreign key linked in a separate table? SQL

So I went through Odoo database design and I saw that they stored the relationship between 2 tables in a separate table that doesn't have primary key. How are you able to do this? I want to replicate this kind of behavior in SQL Server. Is it auto-inserted?
A table should always have a primary key. Look at the thousands of questions on Stackoverflow that ask how to delete one of two identical rows in a database table.
You typically model m-to-n relationships between tables with a separate table that has foreign keys to both tables:
CREATE TABLE person (
person_id bigint PRIMARY KEY,
name text,
...
);
CREATE TABLE game (
game_id bigint PRIMARY KEY,
name text NOT NULL,
...
);
CREATE TABLE likes_to_play (
person_id bigint REFERENCES person NOT NULL,
game_id bigint REFERENCES game NOT NULL,
PRIMARY KEY (person_id, game_id)
);
CREATE INDEX ON likes_to_play (game_id);
The primary key on the table makes sure there are no superfluous double entries and backs one of the foreign keys. The other index is created for the other foreign key.

creating table having foreign key that reference another table

I am using PGAdminIII database.
I have one table named STOCKREGISTER which contains composite primary key consisting of three fields ie stockregisterId,applicationId and date.
I have to create another table STOCK which has a foreignkey field that reference the field stockregisterId of STOCKREGISTER.If I am trying to create STOCK table,an error message is shown.The error message is "there is no unique contraint matching keys for referenced table STOCKREGISTER".What another step I have to take next
this first table
CREATE TABLE stock_register
(
stock_register_id bigint NOT NULL,
application_id bigserial NOT NULL,
production_date date NOT NULL,
opening_bal bigint DEFAULT 0,
quantity_produced bigint,
total_quantity bigint
CONSTRAINT primarykey PRIMARY KEY (stock_register_id, application_id, production_date),
CONSTRAINT "foreignKey" FOREIGN KEY (application_id)
REFERENCES application (application_id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION
)
below is second table.Here I cannot make stock_register_id as a foreign key
CREATE TABLE Stock
(
stock_id bigint NOT NULL,
stock_register_id bigint,
dimension bigserial NOT NULL,
CONSTRAINT "stockid" PRIMARY KEY (stock_id)
)
I guess that syntax should be:
CREATE TABLE Stock
(
stock_id bigint NOT NULL,
stock_register_id bigint,
dimension bigserial NOT NULL,
CONSTRAINT "stockid"
FOREIGN KEY (stock_id)
REFERENCES stock_register (stock_register_id)
)
CREATE TABLE Stock
(
stock_id bigint NOT NULL,
stock_register_id bigint,
dimension bigserial NOT NULL,
CONSTRAINT primaryKey PRIMARY KEY (stock_id),
CONSTRAINT foreignKey FOREIGN KEY(stock_register_id)
REFERENCES stock_register (stock_register_id)
)
That should be everything you need. You'll also have to make sure the DB table engines, collations and charsets match up when using Foreign Keys.
For the unique constraint issue, there doesn't seem to be a problem with your stock_register_id PK in the stock_register table. Based on the name STOCKREGISTER in the error message I suspect it wasn't finding the table stock_register in your second Create statement.
What is a foreign key? A pointer to a specific record in another table.
How is a specific record in stock_register identified according to your DDL? By the unique combination of (stock_register_id, application_id, production_date).
Therefore stock_register_id = 1 could appear on a thousand different records so long as application_id and production_date are different.
Therefore, if all you have is a stock_register_id, there is no way to know which stock_register record it is pointing to and therefore no way for the DBMS to enforce the foreign key.
You must either add application_id and production_date to the stock table and make all three columns together the FK to the composite key on stock_register, or you must remove application_id and production_date from the PK on stock_register so the FK and PK columns match.

SQL Table Foreign Key that is part of a Composite Primary Key

Is it possible to have a table's foreign key be part of another table's composite primary key?
For example, if I have two tables, one contains information on all active projects of different users and another containing information on what equipment is being used by the projects:
Project Table:
Composite Primary Keys: UserId, ProjectId (neither are unique by themselves)
Equipment Table:
Composite Primary Keys: UserId, ProjectId, EquipmentId (neither are unique by themselves)
Now is it possible to set the ProjectId in the equipment table to be a foreign key from the project table? When I try, I get an error saying that the column in Project Table do not match an existing primary key or unique constraint?
No.
When you create a foreign key, the key that you "point to" in the other table must be a UNIQUE or PRIMARY KEY constraint. You cannot establish a foreign key that points to a column that allow duplicate values. It would be very hard to imagine how the data should "act" if you update one of the duplicate values in the other table (for instance).
To do what you want you must establish a Projects table in which ProjectID is UNIQUE or a PRIMARY KEY and then point foreign keys in both the other tables to that table.
Parenthetically, you use the term "Primary Keys" to describe the columns in each table that make up the primary key. In fact, each table can have one and only one primary key. That key can be composed of one or more columns, but the key itself is still referred to in the singular. This is an important difference when using the primary key to optimize searches.
It do not know if that's a good design practice but for sure it is possible to have a composite foreign key of one table that is the part of the composite primary key of other table.
Say we have a table test1 having a composite primary key (A, B)
Now we can have a table say test2 having primary key (P, Q, R) where in (P,Q) of test2 referencing (A,B) of test2.
I ran the following script in the MySql database and it works just fine.
CREATE TABLE `test1` (
`A` INT NOT NULL,
`B` VARCHAR(2) NOT NULL,
`C` DATETIME NULL,
`D` VARCHAR(45) NULL,
PRIMARY KEY (`A`, `B`));
CREATE TABLE `test2` (
`P` INT NOT NULL,
`Q` VARCHAR(2) NOT NULL,
`R` INT NOT NULL,
`S` DATETIME NULL,
`T` VARCHAR(8) NULL,
PRIMARY KEY (`P`, `Q`, `R`),
INDEX `PQ_idx` (`P`,`Q` ASC),
CONSTRAINT `PQ`
FOREIGN KEY (`P`, `Q`)
REFERENCES `test1` (`A`,`B`)
ON DELETE CASCADE
ON UPDATE CASCADE);
In the above mentioned case, the database is expecting the combination of (A,B) to be unique and it is, being a primary key in test1 table.
But if you try to do something like following, the script would fail. The database would not let you create the test2 table.
CREATE TABLE `test2` (
`P` INT NOT NULL,
`Q` VARCHAR(2) NULL,
`R` DATETIME NULL,
`S` VARCHAR(8) NULL,
`T` VARCHAR(45) NULL,
INDEX `P_idx` (`P` ASC),
INDEX `Q_idx` (`Q` ASC),
CONSTRAINT `P`
FOREIGN KEY (`P`)
REFERENCES `test1` (`A`)
ON DELETE CASCADE
ON UPDATE CASCADE,
CONSTRAINT `Q`
FOREIGN KEY (`Q`)
REFERENCES `test1` (`B`)
ON DELETE CASCADE
ON UPDATE CASCADE);
In the above mentioned case database would expect the column A to be unique individually and the same follows for column B. It does not matter if combination of (A,B) is unique.
#Larry Lustig
The foreign key can be part of primary key in the other table.
source: Dependent relationship
Check relationship between tables: Zdarzenie(Event) and TypZdarzenia (type of event)

Foreign keys in MySQL?

I have been slowly learning SQL the last few weeks. I've picked up all of the relational algebra and the basics of how relational databases work. What I'm trying to do now is learn how it's implemented.
A stumbling block I've come across in this, is foreign keys in MySQL. I can't seem to find much about the other than that they exist in the InnoDB storage schema that MySQL has.
What is a simple example of foreign keys implemented in MySQL?
Here's part of a schema I wrote that doesn't seem to be working if you would rather point out my flaw than show me a working example.
CREATE TABLE `posts` (
`pID` bigint(20) NOT NULL auto_increment,
`content` text NOT NULL,
`time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`uID` bigint(20) NOT NULL,
`wikiptr` bigint(20) default NULL,
`cID` bigint(20) NOT NULL,
PRIMARY KEY (`pID`),
Foreign Key(`cID`) references categories,
Foreign Key(`uID`) references users
) ENGINE=InnoDB;
Assuming your categories and users table already exist and contain cID and uID respectively as primary keys, this should work:
CREATE TABLE `posts` (
`pID` bigint(20) NOT NULL auto_increment,
`content` text NOT NULL,
`time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`uID` bigint(20) NOT NULL,
`wikiptr` bigint(20) default NULL,
`cID` bigint(20) NOT NULL,
PRIMARY KEY (`pID`),
Foreign Key(`cID`) references categories(`cID`),
Foreign Key(`uID`) references users(`uID`)
) ENGINE=InnoDB;
The column name is required in the references clause.
Edited: Robert and Vinko state that you need to declare the name of the referenced column in the foreign key constraint. This is necessary in InnoDB, although in standard SQL you're permitted to omit the referenced column name if it's the same name in the parent table.
One idiosyncrasy I've encountered in MySQL is that foreign key declaration will fail silently in several circumstances:
Your MySQL installation doesn't include the innodb engine
Your MySQL config file doesn't enable the innodb engine
You don't declare your table with the ENGINE=InnoDB table modifier
The foreign key column isn't exactly the same data type as the primary key column in the referenced table
Unfortunately, MySQL gives no message that it has failed to create the foreign key constraint. It simply ignores the request, and creates the table without the foreign key (if you SHOW CREATE TABLE posts, you may see no foreign key declaration). I've always thought this is a bad feature of MySQL!
Tip: the integer argument for integer data types (e.g. BIGINT(20)) is not necessary. It has nothing to do with the storage size or range of the column. BIGINT is always the same size regardless of the argument you give it. The number refers to how many digits MySQL will pad the column if you use the ZEROFILL column modifier.
This has some code showing how to create foreign keys by themselves, and in CREATE TABLE.
Here's one of the simpler examples from that:
CREATE TABLE parent (
id INT NOT NULL,
PRIMARY KEY (id)
) ENGINE=INNODB;
CREATE TABLE child (
id INT,
parent_id INT,
INDEX par_ind (parent_id),
FOREIGN KEY (parent_id) REFERENCES parent(id)
ON DELETE CASCADE
) ENGINE=INNODB;
I agree with Robert. You are missing the name of the column in the references clause (and you should be getting the error 150). I'll add that you can check how the tables got created in reality with:
SHOW CREATE TABLE posts;
The previous answers deal with the foreign key constraint. While the foreign key constraint is definitely useful to maintain referential integrity, the concept of "foreign key" itself is fundamental to the relational model of data, regardless of whether you use the constraint or not.
Whenever you do an equijoin, you are equating a foreign key to something, usually the key it references. Example:
select *
from
Students
inner join
StudentCourses
on Students.StudentId = StudentCourses.StudentId
StudentCourses.StudentId is a foreign key referencing Students.StudentId.