CREATE TABLE Orders
-> (
-> ID SMALLINT UNSIGNED NOT NULL,
-> ModelID SMALLINT UNSIGNED NOT NULL,
-> Descrip VARCHAR(40),
-> PRIMARY KEY (ID, ModelID)
-> );
Basically, this appears to me to be creating two primary key on one table. Is that correct?
I thought that we could create a number of unique keys in one table, but only one primary key.
How is it that my system is allowing the creation of multiple primary keys?
Please advise: what are the rules governing this?
Your system is not allowing multiple primary keys - it is creating the key based on 2 columns (ID, ModelID)
Think of it like it suggest, a 'KEY'. So the key would be all of the columns specified. In your case you can have multiple rows with the same 'ID' and multiple rows with the same 'ModelID' but there shall never be two rows that have the same 'ID' AND 'ModelID'.
So in this case it is not saying that the column 'ID' must be unique nor is it saying that 'ModelID' must be unique, but only the combination.
You are making 1 primary key. But that key is a combination of 2 values.
Which is not a wrong thing to do. But in your case it does look wrong.
You seem to have a primary key named ID and a foreign key named ModelID. You should probable have an index on the ModelID, and a primary key constraint on the ID
You can have one primary key (thats why it is called the primary key)
You can have multiple UNIQUE keys if you like.
Related
If the two columns both have unique values of their own whether it is possible to declare both the columns are primary keys ? PS Not talking about declaring a combination of both the columns as composite key.
A primary key in a table has three properties:
The key is NOT NULL (all components).
The key is unique.
There is only one per table.
This is the definition of a primary key in a relational database. The third condition makes it pretty clear that you cannot have two of them in the same table.
On the other hand, you could have one primary key and another key that is defined as UNIQUE and NOT NULL. You can do this as many times as you like.
I'm trying to create a procedure that inserts data into a table of registers but i don't want to repeat the second parameter, this is the table
CREATE TABLE Inscription
(
idClass INT references tb_class,
idStudent INT references tb_student,
)
The idea is that a student (idStudent) can register in various classes but not in the same class (idClass), I tried to add a unique constraint in the idStudent column but that only allows a student to register in one single class.
I always suggest that all tables have a numeric primary key. In addition, your foreign key references are not correct. And what you want to do is add a unique constraint.
The exact syntax depends on the database. The following is for SQL Server:
CREATE TABLE Inscriptions (
idInscription int identity(1, 1) primary key
idClass int references tb_classes(idClass),
idStudent int references tb_students(idStudnt)
unique (idClass, idStudent)
);
Notice that I name the tables as the plural of the entity, but the id using the singular.
The Inscriptions table probably wants other columns as well, such as the date/time of the inscription, the method, and other related information.
You are looking to create a constraint on your table that includes both columns idClass and idStudent.
Once that constraint is created, an attempt to insert duplicate class/student will result in an error being raised.
As your table does not seem to include a primary key, you would better make that constraint your primary key.
NB : you did not tell which RDBMS you are using hence cannot give you the exact syntax to use...
Your unique key needs to encompass both idClass and idStudent, so any particular combination cannot repeat itself.
I have a table with 2 primary key columns : ID and StudentID.
ID column is set to isIdentity = Yes with auto increment.
I've tested it multiple times before, but for some reason this time, when I insert a duplicate value on StudentID, it does not throw the error but instead added it on to the database. 2 of the same values are displayed when I show the table data.
What can be the problem here?
You have a compound primary key on ID and StudentID. That means you the combination of ID and StudentID together must be unique. Since ID is an identity column that combination of ID and StudentID will always be unique (because ID is already unique on its own).
You can change the primary key to be on ID only. Then you can add a unique index on StudentID. For example:
create unique index idx_studentID on yourTable(StudentID)
That will insure that the StudentID column, in fact, contains only unique values.
It seems like you may not actually need ID column, but that's a little wider discussion than your original question.
You can't have 2 "primary keys". You can have a compound primary key (meaning the combination needs to be unique, which is what it sounds like you have now. Or, You can have one "primary" key and one "unique" constraint which is what it sounds like you want.
You cannot have 2 Primary Keys. You can have multiple Unique Keys if needed, which should help you in your case. Make sure to go back to your table creation and double check which column is your Primary Key and work from there.
Do not mix up identity, primary key and unique key.
Any table can have identity key which you can setup on table. Here seed can be say 1, then increment it by 1. So incremental order will like 1,2,3...and so on.
Primary key, one can define on specific column of the table. Identity key can be used as primary key. But you can have identity column as well primary key on same table. Primary key is one and only for the table.So if you are treating identity as primary key, then you will have no further table column as primary key.
Unique key, can be more than one column with your table.
While fetching rows from table data, if you provide combination of identity key, primary key and unique key then search will be fastest
During my first response, I have mentioned that one can generate identity column by soft coding and it will not be treated as primary key.Following is syntax one can use while creating table.
1] If one wish to set identity column as primary key
--id int identity(1,1) primary key
2] If one doesn't wish to set identity column as primary key and still wish
to us identity column then donot us word primary key for identity column.
--id int identity(1,1)
In this 2] case scenario, one may create primary key on other table column.
I'm working on a learning platform where students belong to a team, each of which belongs to a curriculum:
CREATE TABLE teams (
id SERIAL,
name string NOT NULL,
curriculum_id integer NOT NULL
);
CREATE TABLE curricula (
id SERIAL,
name string NOT NULL
);
CREATE UNIQUE INDEX index_curricula_on_name ON curricula USING btree (name);
Curricula have to be unique by name, and while most curricula are allowed to have multiple teams associated to them, one can not. I am trying to add a partial (unique) index on the teams table so as to add a restraint on the curriculum.
I know I can partially constrain the curriculum id itself with...
CREATE UNIQUE INDEX index_teams_on_curriculum_id ON teams USING btree (curriculum_id)
WHERE curriculum_id = 1;
... but this is not viable, as the IDs for the curriculum will vary across environments (dev, staging, etc).
Is there a way to constrain the teams.curriculum_id column by curricula.name instead?
You could implement something like this with a trigger or with a fake immutable function in a CHECK constraint. Both have their weak spots.
But this can also be implemented with pure SQL - only using NOT NULL, CHECK, UNIQUE and FK constraints. No weak spot.
CREATE TABLE curriculum (
curriculum_id serial PRIMARY KEY
, curriculum text UNIQUE NOT NULL
, team_unique boolean UNIQUE NOT NULL
, CONSTRAINT curriculum_team_uni UNIQUE (curriculum_id, team_unique) -- for multicolumn FK
);
CREATE TABLE team (
team_id serial PRIMARY KEY
, team text NOT NULL
, curriculum_id integer NOT NULL
, team_unique boolean NOT NULL
-- , CONSTRAINT fk1 FOREIGN KEY (curriculum_id) REFERENCES curriculum
, CONSTRAINT fk2 FOREIGN KEY (curriculum_id, team_unique)
REFERENCES curriculum (curriculum_id, team_unique)
);
CREATE UNIQUE INDEX team_curriculum_uni_idx ON team (team_unique)
WHERE team_unique;
Add a boolean NOT NULL column to parent and child table and make it UNIQUE in the parent table. So only one row in curriculum can be marked unique - to implement your restrictive requirement:
one can not
A partial unique index team_curriculum_uni_idx enforces only a single reference to it.
If there were multiple unique curriculums (to be referenced once only), we would remove the UNIQUE constraints on curriculum.team_unique and extend the partial unique index on team to (curriculum_id, team_unique).
The FK (fk2) forces to inherit the combination of columns.
This makes it simple to add a UNIQUE constraint to enforce a single team for the unique curriculum.
The default MATCH SIMPLE behavior of Postgres FK constraints only enforces combinations without NULL values. We can either use MATCH FULL or another plain FK (fk1) to enforce only existing curriculum_id. I commented the additional FK since we don't need it in this configuration (both FK columns defined NOT NULL).
SQL Fiddle.
Related:
MATCH FULL vs MATCH SIMPLE in foreign key constraints
CONSTRAINT to check values from a remotely related table (via join etc.)
Disable all constraints and table checks while restoring a dump
Enforcing constraints “two tables away”
Hoping someone can shed some light on this: Do lookup tables need their own ID?
For example, say I have:
Table users: user_id, username
Table categories: category_id, category_name
Table users_categories: user_id, category_id
Would each row in "users_categories" need an additional ID field? What would the primary key of said table be? Thanks.
You have a choice. The primary key can be either:
A new, otherwise meaningless INTEGER column.
A key made up of both user_id and category_id.
I prefer the first solution but I think you'll find a majority of programmers here prefer the second.
You could create a composite key that uses the both keys
Normally if there is no suitable key to be found in a table you want to create a either a composite key, made up of 2 or more fields,
ex:
Code below found here
CREATE TABLE topic_replies (
topic_id int unsigned not null,
id int unsigned not null auto_increment,
user_id int unsigned not null,
message text not null,
PRIMARY KEY(topic_id, id));
therefor in your case you could add code that does the following:
ALTER TABLE users_categories ADD PRIMARY KEY (user_id, category_id);
therefor once you want to reference a certain field all you would need is to pass the two PKs from your other table, however to link them they need to each be coded as a foreign key.
ALTER TABLE users_categories ADD CONSTRAINT fk_1 FOREIGN KEY (category_id) REFERENCES categories (category_id);
but if you want to create a new primary key in your users_categories table that is an option. Just know that its not always neccessary.
If your users_categories table has a unique primary key over (user_id, category_id), then - no, not necessarily.
Only if you
want to refer to single rows of that table from someplace else easily
have more than one equal user_id, category_id combination
you could benefit from a separate ID field.
Every table needs a primary key and unique ID in SQL no matter what. Just make it users_categories_id, you technically never have to use it but it has to be there.