Using group of columns as a unique key in MySQL - mysql

I have a table called requests on which the columns are id, placeId, songId, userId
id is the primary index of the table. Rest of the columns are only unsigned integers and no other unique key is defined.
I want placeId & songId pairs to be unique, i.e., if a row has placeId : 5 and songId : 12, no other rows can have the same combination.
I want this check to happen in SQL level, so that I can query like insert into requests (...) values (...) on duplicate key do something else

you can create a UNIQUE index on multiple columns like this
CREATE UNIQUE INDEX placeSong
ON requests (placeId, songId)

Another method is to add an unique constraint to the table :
ALTER TABLE requests ADD CONSTRAINT placeSong UNIQUE( placeId , songId );

CREATE TABLE `tbl` (
`ID` INT(11) NOT NULL AUTO_INCREMENT,
`field1` VARCHAR(45) NOT NULL DEFAULT '',
`field2` VARCHAR(20) NOT NULL DEFAULT '',
PRIMARY KEY (`ID`),
UNIQUE INDEX `Index 2` (`field1`, `field2`)
);

Related

MySql: The customer has multiple addresses only one is primary

I don't think I planned and organized the table well, so please consider and advise me how to solve this.
In my application I have to ensure that customers can have multiple addresses only one of those addresses must be marked as primary. The primary address is used as the delivery address, etc.
I have customer table and i create new relation table customer_addresses.
CREATE TABLE `customer_addresses` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`custemer_id` int(11) DEFAULT NULL,
`primary_adddrss` tinyint(1) DEFAULT NULL,
`address` varchar(225) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `custemer_id_UNIQUE` (`custemer_id`),
UNIQUE KEY `primary_UNIQUE` (`primary_adddrss`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
This table must contain all the addresses of all customers but only one address from a specific customer must be primary and customer can have only one primary address. That is reson whay i put two unique index.
If i remove custemer_id unique only one primary address can be in whole table for all customers.
Only one primary address per customer other non-primary addresses are null.
Table
id | customer_id | primary_address | address
--------------------------------------------------------
1 1 1 Test
This above customer have only one primary address. Now i want to insert for the some customer more non-primary addresses.
When i try to insert
INSERT INTO `table`.`customer_addresses`(`id`,`custemer_id`,`primary_adddrss`,`address`)
VALUES (1, null ,'Test 2');
I get error
1062: Duplicate entry '1' for key 'primary_UNIQUE'
If i remove primary_UNIQUE than all cusomers can have only one primary. I need one customer only one primary.
How to redesign table to slove this?
Thanks
If the customer may have a lot of different addresses then you have 1:N relation. Create separate addresses table which refers to customers table. Add a column which marks primary address and restrict with only one mark per customer_id.
Schematically (no syntax):
CREATE TABLE customer ( customer_id PRIMARY KEY, ... );
CREATE TABLE address ( address_id PRIMARY KEY,
-- reference to customer
customer_id NOT NULL REFERENCES customer (customer_id),
-- can be either 1 or NULL
is_primary BOOLEAN NULL CHECK (is_primary = 1),
-- allows one 1 and many NULL per customer
UNIQUE (customer_id, is_primary),
... );
DEMO
Option 1 :
CREATE TABLE `customer_addresses` ( `id` INT NOT NULL AUTO_INCREMENT ,
`customer_id` INT NOT NULL ,
`primary_address` TEXT NOT NULL ,
`addresses` TEXT NOT NULL ,
PRIMARY KEY (`id`)) ENGINE = InnoDB;
you can save primary address in primary_address column, and other addresses is saved in addresses column as array
Option 2 :
CREATE TABLE `customer_addresses` ( `id` INT NOT NULL AUTO_INCREMENT ,
`customer_id` INT NOT NULL ,
`is_primary` BOOLEAN NOT NULL ,
`addresses` TEXT NOT NULL ,
PRIMARY KEY (`id`)) ENGINE = InnoDB;
just save all address as usual, and marks the primary address with is_primary=1 and the non-primary address with is_primary=0

Foregin keys returns empty results

I'm using an a mySQL db on localhosts. Created table with primary key and another table with foreign key pointing to that one, but when I want to see the results all I geted is "alert" that MySQL returned emty result. Here my tables
CREATE TABLE example_1(
ex1_id int NOT NULL AUTO_INCREMENT,
first_name varchar(50) NULL,
last_name varchar(50) NULL,
CONSTRAINT example_1_pk PRIMARY KEY (ex1_id)
);
CREATE TABLE example_2 (
ex2_id int NOT NULL AUTO_INCREMENT,
acces_lvl int NOT NULL,
CONSTRAINT example_2_pk PRIMARY KEY (ex2_id)
);
CREATE TABLE example_3 (
ex3_id int NOT NULL AUTO_INCREMENT,
first int NOT NULL,
second int NOT NULL,
CONSTRAINT example_3_pk PRIMARY KEY (ex3_id),
FOREIGN KEY (first) REFERENCES example_1(ex1_id),
FOREIGN KEY (second) REFERENCES example_2(ex2_id)
);
Then I add something to db, eg.
INSERT INTO `example_1`(`first_name`, `last_name`) VALUES ('foo', 'bar');
and
INSERT INTO `example_2`(`acces_lvl`) VALUES (2)
then when I try
SELECT * FROM `example_3`
I have nothing, empty results. Shouldn't be there id's from other tables? Am I doing something wrong, or I didn't do something? I'm totally noob in database.
Because you did not insert any data into example_3. Foreign key constraints don't propagate data, they just enforce the data relationship, so when you do insert data into example_3, the values you put in the columns with foreign key constraints have corresponding values in other table.

Inserting into multiple tables at once

Structure:
Table A)
CREATE TABLE Item (
Id INT(11) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'Unique id of an item',
`By` VARCHAR(50) DEFAULT NULL,
PRIMARY KEY (Id),
CONSTRAINT FK_Item_User_Name FOREIGN KEY (`By`)
REFERENCES User(Name) ON DELETE NO ACTION ON UPDATE CASCADE
)
Table B)
CREATE TABLE ItemName (
Item_Id INT(11) UNSIGNED NOT NULL COMMENT 'Item id this name is referencing',
Language VARCHAR(5) NOT NULL COMMENT 'language code by ISO 639-2/T',
Translation VARCHAR(50) NOT NULL COMMENT 'Item name for given language',
PRIMARY KEY (Item_Id, Language),
CONSTRAINT FK_ItemName_Item_Id FOREIGN KEY (Item_Id)
REFERENCES Item(Id) ON DELETE CASCADE ON UPDATE CASCADE
)
Table C)
CREATE TABLE User (
Name VARCHAR(50) NOT NULL,
Password VARCHAR(50) NOT NULL,
Salt VARCHAR(255) NOT NULL,
Blocked TINYINT(1) DEFAULT 0,
PRIMARY KEY (Name),
UNIQUE INDEX UK_User_Name (Name)
)
Question:
Now I want to insert a new item. Let's say the user provides us with:
Translation
Language code
Username
What i got so far:
I was thinking of puting it in a transaction and inserting into each table after eachother. But then i'm stuck on how do i know what Item.Id to use in the ItemName.Item_Id field since the Item table will AI a new Id for the insert.
I could get the last Item.Id, but then it might be pointing to another item if multiple users were to be inserting a new item simulaneuosly.
ps. Engine=InnoDB
BEGIN;
INSERT into one table;
get the last_insert_id() -- there are many ways to do this, depending on the API
INSERT into next table...
... ;
COMMIT;
Do the inserts in the order that avoids violating your FOREIGN KEYs.

How can I do an insert into to a column when I have a foreign key in mysql

Hello guys I have some problems I have been trying to inser data to a column which have a foreign key in MSQL But I can't make it work. I would appreciate if somebody help me with this.
Category
(
idCategory int(20) auto_increment not null,
NameCategory varchar(40) not null,
PRIMARY KEY (idCategory)
);
SubCategory
(
idSubCategory int(10)not null primary key auto_increment ,
NameSub varchar(40) not null,
FK_Category int not null
);
ALTER TABLE SubCategory auto_increment=1;
ALTER TABLE SubCategory
ADD FOREIGN KEY (PK_Category)
REFERENCES Category (idCategory);
I have tried this 3 ways but nothing works
INSERT INTO Subcategory (NameSub)
VALUES ( 'Nisan');
INSERT INTO Subcategory (idSubCategory, NameSub,PK_Category)
VALUES (01, 'Nisan', 01);
INSERT INTO subcategory (NameSub, PK_Category) VALUES
( 'Nisan' SELECT idCategory from Category WHERE idCategory = 1 );
For some reason your Foreign key constrains script didn't work for me so I did it another an alternate way.
I worked out why afterwards, you reference you have ADD FOREIGN KEY (PK_Category) rather than (FK_Category)
CREATE TABLE Category
(
idCategory int(20) auto_increment not null,
NameCategory varchar(40) not null,
PRIMARY KEY (idCategory)
);
CREATE TABLE SubCategory
(
idSubCategory int(10)not null primary key auto_increment ,
NameSub varchar(40) not null,
FK_Category int not null,
INDEX IDX_Category(FK_Category),
FOREIGN KEY (FK_Category)
REFERENCES Category(idCategory)
ON DELETE CASCADE
);
ALTER TABLE SubCategory auto_increment=1;
And here are the inserts
INSERT INTO Category (NameCategory)
VALUES ('Car');
INSERT INTO Subcategory (NameSub,FK_Category)
VALUES ('Nisan', 01);
As you didn't specify the contents of the table of Category I've created one.
Note: The issue you may be having is that your parent table is empty, and then it would error.
SQL Fiddle

MySQL unique id across multiple tables

I have 2 tables with the following structure:
CREATE TABLE IF NOT EXISTS `car` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT ,
`name` VARCHAR(255) NOT NULL ,
`title` VARCHAR(255) NOT NULL
PRIMARY KEY (`id`) ,
UNIQUE INDEX `name_UNIQUE` (`name` ASC) )
ENGINE = InnoDB;
CREATE TABLE IF NOT EXISTS `book` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT ,
`name` VARCHAR(255) NOT NULL ,
`title` VARCHAR(255) NOT NULL
PRIMARY KEY (`id`) ,
UNIQUE INDEX `name_UNIQUE` (`name` ASC) )
ENGINE = InnoDB;
I generating the name column from the title for example: if title: Foo Bar -> name: foo-bar. I'm using this value in the URL. Eariler i had URLs like this /car/foo-bar or /book/foo-bar having same name value in both table wasnt a problem. But i want shorter URLs now: /foo-bar or /foo-bar-2.
How can I make the name value unique across multiple tables?
If you're building an OO application, you would put the name in a separate table and add foreign keys from books and cars to "names"... or whatever that table means in your application, for example product.
Otherwise you can enforce it with triggers, but I don't know how triggers work in mysql.
If you want to force it to be unique, then you could create a third table called name_reference for example with a prinary key of the combination of the fields name and a field called type. Then you could have book and car have foreign keys to the name_reference.