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.
Related
Am trying to create the following table:
create table Cust (Name varchar(50) UNIQUE, Cat1 varchar(50), RowID int NOT NULL AUTO_INCREMENT, PRIMARY KEY (Name));
the error I get is
Incorrect table definition; there can be only one auto column and it
must be defined as a key
I want to index by the "Name", not the RowID. So even if I end it with:
...PRIMARY KEY (Name, RowID));
It fails. Of course ...PRIMARY KEY (RowID, Name)); works but is not what I want.
Can someone help me see the light please?
Thanks
You just need to make a KEY (aka index) for the auto-inc column. It doesn't have to be the primary key, but it must be the left-most column in some index.
create table Cust (
Name varchar(50),
Cat1 varchar(50),
RowID int NOT NULL AUTO_INCREMENT,
PRIMARY KEY (Name),
KEY (RowId)
);
Don't add the UNIQUE option to the name column. That creates an extra superfluous unique index, which you don't need. Any PRIMARY KEY is already unique.
I'll comment that auto-inc is not the same thing as rowid. Don't expect auto-inc to have consecutive values.
I have two mysql tables. The first one is created using the following code:
create table project(
project_id int not null auto_increment,
project_name varchar(30)
primary key(project_id));
The second table:
create table matches(
match_id int not null auto_increment,
match_name varchar(30),
project_id int(4) foreign key (project_id) references projects(project_id));
Both these commands works fine. I want to add the project_name column from the first table to the second table. I tried using
alter table projects drop primary key, add primary key(project_id, project_name);
and then
alter table matches add column project_name varchar(30), add foreign key (project_name) references projects(project_name);
But got the following error:
ERROR 1005 (HY000): Can't create table 'matches.#sql-55e_311' (errno: 150)
How do i include both the columns from the first table into the second table.
The current structure of my second table is as follows:
+------------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+-------------+------+-----+---------+----------------+
| match_id | int(11) | NO | PRI | NULL | auto_increment |
| match_name | varchar(30) | YES | | NULL | |
| project_id | int(4) | NO | MUL | NULL | |
+------------+-------------+------+-----+---------+----------------+
I want to add the project_name as the fourth column in my second table.
To use a compound Primary Key as Foreign Key, you'll have to add the
same number of columns (that compose the PK) with same datatypes to
the child table and then use the combination of these columns in the
FOREIGN KEY definition.
see related post here https://stackoverflow.com/a/10566463/4904726
so try this way
alter table matches add foreign key (project_id, project_name) references projects(project_id, project_name);
Do you understand what a FK constraint says? It says a list of values for some columns in a table must appear as a list of values for some columns forming a (declared) PK or UNIQUE NOT NULL in the referenced table. So what you are writing doesn't make sense. If you wanted a PK (project_id, project_name) then that should also be the form of your FK.
But (project_id, project_name) is not two 1-column PKs, it is one 2-column PK, and it is probably not what you want since presumably in projects it isn't just pairs that are unique it is each column. Presumably you want two 1-column PKs and two one-column FKs, one referencing each PK.
If projects project_id was NOT NULL you could write:
alter table projects add primary key(project_name);
alter table matches add column project_name varchar(30),
add foreign key (project_name) references projects(project_name);
But if project_name can be NULL in projects then you cannot make it a PK and you cannot sensibly have a FK to it. You can make it UNIQUE. Unfortunately MySQL lets you write such a FK declaration to a non-NULL UNIQUE column while it also tells you not to do it:
The handling of foreign key references to non-unique keys or keys that contain NULL values is not well defined for operations such as UPDATE or DELETE CASCADE. You are advised to use foreign keys that reference only keys that are both UNIQUE (or PRIMARY) and NOT NULL.
So if you want projects project_name to be nullable then should declare it UNIQUE but you should enforce the logical matches project_name match with a trigger.
I am not entirely sure what to search so I apologize if this is in fact a duplicate.
I have a table (or at least would like to) as follows:
ID
Company Name
SomeOtherInfo
The primary key would be ID and Company name (composite primary key). What I would like is so that the ID auto increments on each company.
Ex:
1-google
2-google
3-google
1-yahoo
4-google
2-yahoo
This way they are always unique, but each one increments for each company individually.
Is this possible from simple SQL create commands, would rather not have 2 tables and join them using a secondary ID.
Let me know, thanks.
If I follow the question. Create a single table with an identity on the ID column. Then create a unique index on the Company Name.
MySql Version
CREATE TABLE Company (
CompanyID int NOT NULL AUTO_INCREMENT,
CompanyName varchar(255) NOT NULL,
OtherData varchar(255),
PRIMARY KEY (CompanyID)
);
CREATE UNIQUE INDEX CompanyUniqueComposite
ON Company (CompanyID , CompanyName );
I'm sure this is simple stuff to many of you, so I hope you can help easily.
If I have a MySQL table on the "many" side of a "one to many" relationship - like this:
Create Table MyTable(
ThisTableId int auto_increment not null,
ForeignKey int not null,
Information text
)
Since this table would always be used via a join using ForeignKey, it would seem useful to make ForeignKey a clustered index so that foreign keys would always be sorted adjacently for the same source record. However, ForeignKey is not unique, so I gather that it is either not possible or bad practice to make this a clustered index? If I try and make a composite primary key using (ForeignKey, ThisTableId) to achieve both the useful clustering and uniqueness, then there is an error "There can only be one auto column and it must be defined as a key".
I think perhaps I am approaching this incorrectly, in which case, what would be the best way to index the above table for maximum speed?
InnoDB requires that if you have an auto-increment column, it must be the first column in a key.
So you can't define the primary key as (ForeignKey, ThisTableId) -- if ThisTableId is auto-increment.
You could do it if ThisTableId were just a regular column (not auto-increment), but then you would be responsible for assigning a value that is at least unique among other rows with the same value in ForeignKey.
One method I have seen used is to make the column BIGINT UNSIGNED, and use a BEFORE INSERT trigger to assign the column a value from the function UUID_SHORT().
#ypercube correctly points out another solution: The InnoDB rule is that the auto-increment column should be the first column of some key, and if you create a normal secondary key, that's sufficient. This allows you to create a table like the following:
CREATE TABLE `MyTable` (
`ForeignKey` int(11) NOT NULL,
`ThisTableId` int(11) NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`ForeignKey`,`ThisTableId`),
KEY (`ThisTableId`)
) ENGINE=InnoDB;
And the auto-increment works as expected:
mysql> INSERT INTO MyTable (ForeignKey) VALUES (123), (234), (345), (456);
mysql> select * from MyTable;
+------------+-------------+
| ForeignKey | ThisTableId |
+------------+-------------+
| 123 | 1 |
| 234 | 2 |
| 345 | 3 |
| 456 | 4 |
+------------+-------------+
I have here some problems undersanding how this works.
So I have 2 tables Students and Enrolled like this:
CREATE TABLE Students
(sid CHAR(20),
name CHAR(50),
email CHAR(30),
age INTEGER,
gr INTEGER)
CREATE TABLE Enrolled
(sid CHAR(20),
cid CHAR(20),
grade CHAR(2),
PRIMARY KEY (sid,cid))
So I don't understand this particulary row PRIMARY KEY (sid,cid)
Can someone explain to me how it works? I have to specify that I have another table Courses from where the cid.
Is is equivalent saying like this:
CREATE TABLE Enrolled
(sid CHAR(20) foreign key references Students(sid),
cid CHAR(20) foreign key references Courses(cid)
)
A PRIMARY KEY is used to identify a table. A field or column that is defined as PRIMARY KEY will contains different values on each row in that table, and is mandatory to have a value (so, PRIMARY KEY is equivalent to UNIQUE and NOT NULL).
PRIMARY KEY can be a single field, or multiple fields, but it always satisfy that "each row will have a different PRIMARY KEY".
If you declare as PRIMARY KEY a combination of 2 columns, you will be able to have this for example:
CREATE TABLE Enrolled
(sid CHAR(20),
cid CHAR(20),
grade CHAR(2),
PRIMARY KEY (sid,cid)) --PRIMARY KEY with combination of 2 columns
sid | cid | grade
1 1 XX
1 2 XX
2 1 XX
2 2 XX
2 3 XX
In this example, you can see that the column sid or the column cid has repeated values individually, but there isn't a combination of (sid, cid) that was repeated.
Like a PRIMARY KEY is used to identify a row in a table, when we want to relate two tables we can define a FOREIGN KEY in one table to link this one with the other table.
Your case is that the ENROLLED table is identified by a composite PRIMARY KEY to represent a many-to-many relationship. That is the way to say that:
A student can be enrolled in many courses.
A course can have enrolled many students.
Note*: Is a best practice to define the PRIMARY KEYS as numeric values, such integer, bigint, etc. because it is better to improve the indexes performance (all PRIMARY KEYS have defined inherently an INDEX, and they are faster working with "numeric" values than working with "string" values).
PRIMARY KEY (sid,cid) means composite primary key.. the combination of these field should be unique.
PRIMARY KEY means both UNIQUE and NOT NULL.
If you want sid and cid to also be FOREIGN KEY you have to specify that separately.
Having two fields for a primary key is often used for tables that are the physical representation of a many-to-many relation. In your database design diagram you would have STUDENT and COURSE as entities and ENROLLMENT as a many-to-many relationship between them.
In the physical database diagram many-to-many relationships are modelled as tables, often with a composite PRIMARY KEY and with FOREIGN KEY constraints to the entity tables.