I have this kind problem regarding sql:
Table 1: ID_1 (Primary Key) | NAME | LASTNAME | EMAIL...
Table 2: ID_2 (Primary Key) | NAME2 | LASTNAME2 | EMAIL...
Normally using constraints it is possible to make as column in TABLE 2
(NAME 2 for example) as a foreign key for NAME the first TABLE 1.
The general relation would be one-many. That's one value from column NAME in TABLE 1 used many times in column NAME2 in Table 2.
Now what I want to achieve is that making the rule one-to-one, so I cannot have duplicated values of NAME from table TABLE 1 in TABLE 2.
Does it require triggers or it can be set by constraint when creating the tables?
Steps to achieve this:
Create foreign key constraint
Create unique constraint
This can all be done while creating the table.
CREATE TABLE table2 (
...,
name2 varchar(255),
FOREIGN KEY (name2) REFERENCES table1(name),
UNIQUE (name2)
);
If you already have the table, use ALTER TABLE instead.
When trying to insert a row with value of name2 that is already in a table, an error will be raised.
Yes it can be set by constraint. You can have foreign keys and unique keys on the same field. The unique constraint will guarantee there is only one record with one reference to the primary table (from that foreign table)
Related
When I add a foreign key to a table that already has data, what does each of these database management systems do?
Do they analyze each value of the column to confirm it is a value from the referenced table primary key ?
Or do they have some other optimized mechanism ? And if that's the case, what is that mechanism ?
I can't confirm for MonetDB, but in PostgreSQL and MySQL (and most probably on MonetDB too) the answer is yes, they will check every value and will raise an error if the key does not exists on the referenced table.
Notice that the referenced column doesnt need to be the primary key for the referenced table - you can reference any column as a foreign key to the other table.
Yes, of course, a constraint that is not enforced would make no sense.
You can just try(this is for Postgres):
DROP SCHEMA tmp CASCADE;
CREATE SCHEMA tmp ;
SET search_path=tmp;
CREATE TABLE one
( one_id SERIAL NOT NULL PRIMARY KEY
, name varchar
);
INSERT INTO one(name)
SELECT 'name_' || gs::text
FROM generate_series(1,10) gs ;
CREATE TABLE two
( two_id SERIAL NOT NULL PRIMARY KEY
, one_id INTEGER -- REFERENCES one(one_id)
);
INSERT INTO two(one_id)
SELECT one_id
FROM one ;
DELETE FROM one WHERE one_id%5=0;
ALTER TABLE two
ADD FOREIGN KEY (one_id) REFERENCES one(one_id)
;
\d one
\d two
Result:
NOTICE: drop cascades to 2 other objects
DETAIL: drop cascades to table tmp.one
drop cascades to table tmp.two
DROP SCHEMA
CREATE SCHEMA
SET
CREATE TABLE
INSERT 0 10
CREATE TABLE
INSERT 0 10
DELETE 2
ERROR: insert or update on table "two" violates foreign key constraint "two_one_id_fkey"
DETAIL: Key (one_id)=(5) is not present in table "one".
Table "tmp.one"
Column | Type | Modifiers
--------+-------------------+------------------------------------------------------
one_id | integer | not null default nextval('one_one_id_seq'::regclass)
name | character varying |
Indexes:
"one_pkey" PRIMARY KEY, btree (one_id)
Table "tmp.two"
Column | Type | Modifiers
--------+---------+------------------------------------------------------
two_id | integer | not null default nextval('two_two_id_seq'::regclass)
one_id | integer |
Indexes:
"two_pkey" PRIMARY KEY, btree (two_id)
The error message is the same as for an actual insert or update. And you can see that the engine bails out once it en counters the first conflicting row.
I have a table gm_foldernames and it has only one column.names type varchar(255). That column is a foreign key to another table in the bd, table1. I want to turn that column of names into a row maintaining the foreign key structure.
i am using group_concat() to put the cells in column table into a row seperated by comma. however, when i do that i lose my foreign key. I wanna keep the foreign key structure
here is my code;
SELECT GROUP_CONCAT(names) As names FROM gm_foldernames;
this is my current table. names is foreign key referencing another table
*names
ABRUZZO
ANZA
AQABA
...
...
...
I would like maintain the foreign key structure and make the column--> rows
ABRUZZO | ANZA | AQABA | ...
with the new column names being foreign key to the other table in the db
How can I define a primary key in my table as two unique fields?
I have several columns in my table and I have two keys: ID and SOURCE. Values for ID can appear twice in the column, but the combination of ID + SOURCE can be relied on as a primary key.
For example:
ID | SOURCE | TEXT
------------------
UNIQUE - 2312 | FB | BLA BLA
UNIQUE - 2312 | MU | BLA BLA
I'm using MySQL database. How I can I make the primary key on two columns?
You may use the ALTER TABLE syntax, like this:
ALTER TABLE my_table ADD CONSTRAINT my_table_pk PRIMARY KEY (id, source);
Also, this can be defined in CREATE TABLE, like this:
CREATE TABLE my_table
(
id int,
source varchar(3),
text varchar(20),
PRIMARY_KEY(id, source)
)
Add a constraint to enforce uniqueness enforced on two columns:
Alter table table_name add CONSTRAINT constr_ID unique (ID,SOURCE);
OR add a constraint primary key enforced on two columns:
Alter table table_name add PRIMARY KEY (id, source);
Say I have
ID | PRODUCT
1 | Apples
1 | Oranges
1 | Bananas
2 | Walnuts
2 | Almonds
3 | Steak
3 | Chicken
Is this possible to have this type of setup in MySQL? I created a test table, and made an ID column with primary index and auto incrementing. When I try to insert a couple rows all having the same ID, mysql returns an error.
Is this possible to do in mysql?
How did the duplicate records (ID) INSERTED when you set ID as Primary Key? Basically, it will not. Primary Keys are UNIQUE. If you want records to be like that, make another column which served as your primary key
CREATE TABLE sampleTable
(
ID INT NOT NULL AUTO_INCREMENT,
GROUP_ID INT NOT NULL,
PRODUCT VARCHAR(25),
CONSTRAINT pk_name PRIMARY KEY (ID),
CONSTRAINT uq_name UNIQUE (GROUP_ID, PRODUCT)
)
a UNIQUE constraint was added so to avoid duplicated rows.
That is possible, but it is not normalized as you have a repeating primary key. Primary keys must be unique, which means 1 can only occur once. If you have custom ID's for each product, then either use a compound primary key (id, product) or a surrogate key. A surrogate key would be an auto incrementing column that uniquely identifies the row. Your table would then look like this:
CREATE TABLE fruits (
auto_id int AUTO_INCREMENT PRIMARY KEY,
id int,
product varchar(15))
You mustn't create a primary key for the ID column, as this implies that it's unique.
Just take a normal index for your example.
On the other hand, in most cases, it makes sense to have a primary key, so I'd recommend adding a 3rd row (GENRE?) with a normal INDEX on it and leaving the primary key as it is.
When inserting data, just insert the GENRE and the PRODUCT, the ID will be automatically filled.
Doing my first tryouts with foreign keys in a mySQL database and are trying to do a insert, that fails for this reason: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails
Does this mean that foreign keys restrict INSERTS as well as DELETES and/or UPDATES on each table that is enforced with foreign keys relations?
Thanks!
Updated description:
Products
----------------------------
id | type
----------------------------
0 | 0
1 | 3
ProductsToCategories
----------------------------
productid | categoryid
----------------------------
0 | 0
1 | 1
Product table has following structure
CREATE TABLE IF NOT EXISTS `alpha`.`products` (
`id` MEDIUMINT UNSIGNED NOT NULL AUTO_INCREMENT ,
`type` TINYINT(2) UNSIGNED NOT NULL DEFAULT 0 ,
PRIMARY KEY (`id`) ,
CONSTRAINT `funkyfunky`
FOREIGN KEY (`id` )
REFERENCES `alpha`.`ProductsToCategories` (`productid` )
ON DELETE CASCADE,
ON UPDATE CASCADE)
ENGINE = InnoDB;
Your insert is failing because the foreign key in the row you are inserting doesn't match a valid key in the constraint table. For example:
Assume you've got these two tables:
Employees
----------------------------
EmpID | Name
----------------------------
0 | John
1 | Jane
OfficeAssignments
----------------------------
OfficeID | EmpID
----------------------------
0 | 0
1 | 1
If you have a foreign key constraint on OfficeAssignments.EmpID -> Employees.EmpID, and you try to execute:
INSERT INTO OfficeAssignments (OfficeID, EmpID) VALUES (2,2)
The statement will fail because there is no entry in the Employees table with an EmpID of 2.
Constraints are designed to ensure that your dependent table always has valid data with regard to the parent table -- in this example, you will never have an office which is listed as assigned to an employee who doesn't exist in the system, either because they never existed (as in this case) or because they've been deleted (because the constraint will prevent the employee record from being deleted until the office assignment record has been deleted first).
Edit: Now that you've posted the constraint, it indeed looks like it might be set up backwards. By placing the constraint in the definition of the Products table, you are making it the child, and ProductsToCategories the parent. The constraint you've written can be read as, "a Product must be assigned to a category before it can be created". I suspect what you meant is the other way around: "a Product must be created before it can be assigned to a category." To get that result, you need to place the constraint on the ProductsToCategories table, setting the foreign key to productid and referencing Products.id.
You cannot delete a row from the parent table while there is a foreign key reference to it from a child table. Also you cannot insert/update in the child table with invalid id's in the foreign key column.
Edit: The "CONSTRAINT funkyfunky FOREIGN KEY (id)" must be declared in the "ProductsToCategories" table not in the "Products" table, because "ProductsToCategories" is referencing "Products" not the opposite as you have did.
Your products table is slightly wrong, as you don't need to reference anything from it. References go in the "other" tables, and point to the main, e.g:
create table products (
id int auto_increment,
type int,
primary key (id)
);
create table categories (
id int auto_increment,
name varchar(128),
primary key (id)
)
create table products_to_categories (
product_id int references products,
category_id int references categories
);
A foreign key enforces a valid relation between the rows in two tables. In order to be able to insert a row into a table containing a foreign key, there must be a row in the referenced table containing that key or the insert will fail. The same with delete, you can't delete the row in the referenced table while there are still rows in the table with the foreign key that still reference it. The prevents ending up with rows in the dependent table that have data, but don't have associated rows in the referenced table, i.e., a violation of referential integrity.