Declaring MySQL PK as only Unique Key - mysql

Can creating a UNIQUE index on an Id as shown in the create table below be enough to make the id a Primary Key? TO be more specific, can you say that the table below has a Primary Key?
test` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`role` varchar(32) NOT NULL,
`resources_name` varchar(32) NOT NULL,
`access_name` varchar(32) NOT NULL,
`allowed` int(3) NOT NULL,
UNIQUE KEY `id` (`id`),
UNIQUE KEY `roles_name` (`role`,`resources_name`,`access_name`)
) ENGINE=InnoDB AUTO_INCREMENT=32 DEFAULT CHARSET=utf8
What query can you use to prove that this has or has no PK?

Logically speaking if a relational table has at least one candidate key enforced in it (minimally unique and non-nullable) then de facto it has a "primary" key. There is no absolute need to single out any one key using a special "primary" label because in principle all keys are equal (historically the term "primary key" used to be used for any and all candidate keys and not just one key per table).
There is a constraint in SQL called a PRIMARY KEY constraint. Logically speaking, the SQL PRIMARY KEY isn't much more than syntactical sugar because the NOT NULL UNIQUE syntax achieves essentially the same thing. Technically the PRIMARY KEY constraint doesn't have to refer to the same thing as the relational concept of a "primary key" but clearly if you are going to designate any one key as primary and if you feel you need a syntactical way of indicating that choice then the PRIMARY KEY constraint is the generally recognised way to do it.
So perhaps the best answer is "it depends". It depends to a large extent on your motivation for defining a primary key in the first place. If you intend to single out one key to developers and users of the database then maybe the NOT NULL UNIQUE syntax won't achieve that for you. If you don't find the need to do that using SQL syntax then maybe NOT NULL UNIQUE is just as good a way to define your keys as the PRIMARY KEY constraint is.

This is either too long or too short for a comment: No.
A primary key and a unique key -- although similar -- are not the same. So, no your table does not have a primary key. The biggest functional difference is that primary keys cannot be NULL whereas unique keys can be.
Primary keys are also typically clustered (if the underlying storage engine supports clustered indexes). This means that the data is actually physically stored on the page in the order of the primary key. Unique keys are just another index with the characteristic of having no repeated values.
EDIT:
Interesting. SHOW COLUMNS documents this behavior:
A UNIQUE index may be displayed as PRI if it cannot contain NULL
values and there is no PRIMARY KEY in the table.
I wasn't aware of this.

Related

which table is faster in MYSQL?

Two tables:
CREATE TABLE `htmlcode_1` (
`global_id` int(11) NOT NULL,
`site_id` int(11) NOT NULL,
PRIMARY KEY (`global_id`),
KEY `k_site` (`site_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `htmlcode_2` (
`global_id` int(11) NOT NULL,
`site_id` int(11) NOT NULL,
PRIMARY KEY (`site_id`,`global_id`),
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
which one should be faster for selects and why?
'select * from table where site_id=%s'
The latter table is probably slightly faster for that SELECT query, assuming the table has a nontrivial number of rows.
When querying InnoDB by primary key, the lookup is against the clustered index for the table.
Secondary key lookups require a lookup in the index, then that reveals the primary key value, which is then used to do a lookup by primary key. So this uses two lookups.
The reason to use a PRIMARY KEY is to allow for either quick access OR REFERENTIAL INTEGRITY (CONSTRAINT ... FOREIGN KEY ...)
In your second example, you do not have the proper key for referential integrity if any other table refers to your table. In that case, other operations will be very very slow.
The differences in speed in either case for your particular case should be too small and trivial, but the proper design will dictate the first approach.
The first table represents many "globals" in each "site". That is, a "many-to-one" relationship. But it is the "wrong" way to do it. Instead the Globals table should have a column site_id to represent such a relationship to the Sites table. Meanwhile, the existence of htmlcode_1 is an inefficient waste.
The second table may be representing a "many-to-many" relationship between "sites" and "globals". If this is what you really want, then see my tips . Since you are likely to map from globals to sites, another index is needed.

MySQL. UNIQUE and PRIMARY KEY constraints for the same field

I found some legacy code, which sets two almost identical constraints (UNIQUE and PRIMARY KEY) for the primary key field.
Here is the code sample:
CREATE TABLE foofoo (
id NUMERIC(9) NOT NULL ,
bar VARCHAR(40) NOT NULL,
CONSTRAINT PK_foofoo PRIMARY KEY (id),
CONSTRAINT UNIQUE_foofoo UNIQUE(id)
)
I think it's redundant to have these two set and PRIMARY KEY would do the job.
Of course, I read what's the difference between these two constraints, but
what's the point of setting these two constraints for the same field?
There is no point in doing so. A primary key is always unique by nature. I would advise against making both indexes, as indexes comes with a cost (mainly disk space). Just create the PK and you'll be good!
There is no point on setting the exact same constraint as the PK.
A Primary Key is already making sure that this column is unique and indexed.
I think it's redundant ...
Yes indeed it's redundant; since having primary key constraint on the column anyways will make sure that the column has only unique value. There is no point in defining an extra UNIQUE constraint on the same column.
when you declare primary then:
*PRIMARY KEY constraint uniquely identifies each record in a database table
*Primary keys must contain UNIQUE values
so their is no need to declare primary key unique because whenever u declare anything primary key then UNIQUE value is already attached with them.
For unique key:
*The UNIQUE constraint uniquely identifies each record in a database table.
*The UNIQUE and PRIMARY KEY constraints both provide a guarantee for uniqueness for a column or set of columns.
*A PRIMARY KEY constraint automatically has a UNIQUE constraint defined on it.
The most important point is that
*Note that you can have many UNIQUE constraints per table, but only one PRIMARY KEY constraint per table.
In mysql when i take same as primary key and Unique then it gave me error

do we have to explicitly mention the not null constraint for a primary key?

Do we have to explicitly mention that a primary key shouldn't be null, when creating a table? Even if we don't mention the 'not null' constraint for the primary key, SQL wouldn't allow us to insert a NULL value into the primary key field. therefore which of the following is a good practice?
1) create table registration(
id int primary key,
name varchar(10)
)
2) create table registration(
id int primary key not null,
name varchar(10)
)
No you don't.
A PRIMARY KEY is a unique index where all key columns must be defined
as NOT NULL. If they are not explicitly declared as NOT NULL, MySQL
declares them so implicitly (and silently). A table can have only one
PRIMARY KEY. The name of a PRIMARY KEY is always PRIMARY, which thus
cannot be used as the name for any other kind of index.
I'd however consider it good practice to state it explicitly - as that makes things more clear,
and you don't have to look it up this rule every time you're in doubt.
Ask yourself, for the sake of it, why would you not if it makes something, not necessarily less clear without it, but more explicitly clear? Following this, I see no reason to omit it and perfectly valid reasons to emit it in the script.
The best practice is generally the most sensible one.

Difference between Unique Key and Primary Keys

I came across the following SQL in a book:
CREATE TABLE 'categories'(
id SMALLINT NOT NULL AUTO INCREMENT,
category VARCHAR(30) NOT NULL,
PRIMARY KEY('id'),
UNIQUE KEY 'category'('category')
)ENGINE=MyISAM DEFAULT CHARSET = utf8;
I was wondering is there a reason why I would need a PRIMARY and UNIQUE KEY in the same table? I guess, underlying that question is, what is the difference between PRIMARY and UNIQUE keys?
The relational model says there's no essential difference between one key and another. That is, when a relation has more than one candidate key, there are no theoretical reasons for declaring that this key is more important than that key. Essentially, that means there's no theoretical reason for identifying one key as a primary key, and all the others as secondary keys. (There might be practical reasons, though.)
Many relations have more than one candidate key. For example, a relation of US states might have data like this.
State Abbr Postal Code
--
Alabama Ala. AL
Alaska Alaska AK
Arizona Ariz. AZ
...
Wyoming Wyo. WY
It's clear that values in each of those three columns are unique--there are three candidate keys.
If you were going to build a table in SQL to store those values, you might do it like this.
CREATE TABLE states (
state varchar(15) primary key,
abbr varchar(10) not null unique,
postal_code char(2) not null unique
);
And you'd do something like that because SQL doesn't have any other way to say "My table has three separate candidate keys."
I didn't have any particular reason for choosing "state" as the primary key. I could have just as easily chosen "abbr" or "postal_code". Any of those three columns can be used as the target for a foreign key reference, too.
And as far as that goes, I could have built the table like this, too.
CREATE TABLE states (
state varchar(15) not null unique,
abbr varchar(10) not null unique,
postal_code char(2) not null unique
);
I'm surprised that nobody mentionned that a primary key can be referenced as foreign key into other tables.
Also an unique constraint allows NULL values.
The reason you need two uniqueness restrictions (one being the Primary Key) is that you are using Id as a surrogate key. I.e., it is an arbitrary value that has no meaning in relation to the data itself. Without the unique key (or colloquially known as "business key" i.e, a key that the user would recognize as being enforced), a user could add two identical category values with different arbitrary Id values. Since users should never see the surrogate key, they would not know why they are seeing a duplicate even though the database would think they are different.
When using surrogate keys, having another unique constraint on something other than the surrogate key is critical to avoid duplicate data.
Depending on who you talk to and how they read the specification, Unique keys( which is redundant by the way. A "key" is by definition unique) are also not supposed to allow nulls. However, one can also read the specifications as saying that Unique constraints, unlike Primary Key constraints, are in fact supposed to allow nulls (how many nulls are allowed also varies by vendor). Most products, including MySQL, do allow nulls in Unique constraints whereas Primary Key constraints do not.
Similarity
Both a PRIMARY and UNIQUE index create a constraint that requires all values to be distinct (1).
Difference
The PRIMARY key (implicitly) defines all key columns as NOT NULL; additionally, a table can only have one primary key.
(1) Each NULL value is considered to be distinct.
A UNIQUE constraint and PRIMARY key both are similar and it provide unique enforce uniqueness of the column on which they are defined.
Some are basic differences between Primary Key and Unique key are as follows.
Primary key
Primary key cannot have a NULL value.
Each table can have only single primary key.
Primary key is implemented as indexes on the table. By default this index is clustered index.
Primary key can be related with another table's as a Foreign Key.
We can generate ID automatically with the help of Auto Increment field. Primary key supports Auto Increment value.
Unique Constraint
Unique Constraint may have a NULL value.
Each table can have more than one Unique Constraint.
Unique Constraint is also implemented as indexes on the table. By default this index is Non-clustered index.
Unique Constraint cannot be related with another table's as a Foreign Key.
Unique Constraint doesn't support Auto Increment value.
You can find detailed information from: http://www.oracleinformation.com/2014/04/difference-between-primary-key-and-unique-key.html

What's the point of adding NOT NULL to primary key field in MySQL?

What's the point of adding NOT NULL to a primary key field? Primary key is already not null + unique.
Here is an example:
CREATE TABLE student (
id int(11) AUTO_INCREMENT NOT NULL,
name varchar(255),
PRIMARY KEY(id)
)
Why not to define it like this instead:
CREATE TABLE student (
id int(11) AUTO_INCREMENT,
name varchar(255),
PRIMARY KEY(id)
)
They are the same. Primary key got NOT NULL automatically.
You are asking, why do people bother adding the NOT NULL when it is unnecessary? Just because it is good style, I guess. And makes it explicit to the reader.
NULL is not equivalent to NULL(as NULL indicates an unknown or absent value), so you will be permitted to have multiple records that have NULL for the id, even though there's a primary key / unique constraint defined, hence the use of NOT NULL. That's if MySql even allows you to define a primary key on a nullable field.
In addition, as a primary key is often used in a foreign key in other tables, having one or more NULL values wouldn't make sense.
If PRIMARY KEY is declared without NOT NULL, NOT NULL is added to PRIMARY KEY implicitly so PRIMARY KEY with or without NOT NULL is the same.
The MySQL documentation says as shown below:
A unique index where all key columns must be defined as NOT NULL. If
they are not explicitly declared as NOT NULL, MySQL declares them so
implicitly (and silently). A table can have only one PRIMARY KEY. The
name of a PRIMARY KEY is always PRIMARY, which thus cannot be used as
the name for any other kind of index.
And also, the MySQL documentation says as shown below:
The primary key for a table represents the column or set of columns
that you use in your most vital queries. It has an associated index,
for fast query performance. Query performance benefits from the NOT
NULL optimization, because it cannot include any NULL values. ...