creating primary keys with constraints or not in mysql - mysql

In mysql, say I have:
create table users(
id not null
)
Let's say I need to make id as a primary key. What is the difference between:
create table users(
id primary key not null
)
and
create table users(
id not null
primary key (id))
and
create table users(
id not null
constraint pk primary key (id))
I've been searching a lot for the meaning of constraints in this context, but I only find how to use them, not what it actually is.

A primary key is both not null and unique. So, this is very, very similar to a primary key:
create table users (
id int not null unique
)
The one additional feature of a primary key is that it is usually also the clustered index for the table.
A primary key declaration is a constraint. It has the following properties:
The columns are not null.
The columns are unique.
Only one primary key declaration is allowed per table (although multiple columns can be in the primary key).
In addition, the primary key columns often form a clustered index.
Except for the third condition, it is possible to declare these using multiple constraint declarations.

Related

Can I add Primary Key with many condition

I've first table name "mustahik_perorangan" and the second name "data_mustahik"
mustahik perorangan have 4 primary key and foreign key in another table
like this condition
PRIMARY KEY (`mustahik_nik`,`ins_provinces_code`,`ins_cities_code`,`ins_institution_types_code`,`ins_institution_serial_no`),
KEY `fk_reference_6` (`ins_provinces_code`,`ins_cities_code`,`ins_institution_types_code`,`ins_institution_serial_no`),
CONSTRAINT `FK_ins_musper` FOREIGN KEY (`ins_provinces_code`, `ins_cities_code`, `ins_institution_types_code`, `ins_institution_serial_no`) REFERENCES `baznasgo_s_organization`.`institutions` (`provinces_code`, `cities_code`, `institution_types_code`, `institution_serial_no`) ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=latin1
and i want to add primary to table mustahik_perorangan, so mustahik perorangan have 5 primary key ?
but i can't do it because it condition..
ALTER TABLE mustahik_perorangan ADD idc INT UNSIGNED NOT NULL AUTO_INCREMENT,ADD PRIMARY KEY (`idc`);
May you know to do it ?
A table can have at most one primary key constraint.
The primary key constraint can contain multiple columns. We refer to that as a composite key.
It is possible to add a new column.
It's also possible to add a UNIQUE constraint on the column and specify AUTO_INCREMENT attribute on the column.
As an example:
ALTER TABLE mustahik_perorangan
ADD idc INT UNSIGNED NOT NULL AUTO_INCREMENT
, ADD UNIQUE KEY (`idc`)
It's also possible to a sixth column to the existing composite primary key. But I don't think this is what you really want.
As a demonstration of how to add a column to an existing composite primary key, I'll provide an example.
Note that the primary key must be dropped and re-added. And a UNIQUE key must be added for the AUTO_INCREMENT column.
Assuming there are no foreign keys referencing the primary key of this table.
ALTER TABLE mustahik_perorangan
DROP PRIMARY KEY
, ADD idc INT UNSIGNED NOT NULL AUTO_INCREMENT
, ADD UNIQUE KEY (`idc`)
, ADD PRIMARY KEY
(`mustahik_nik`
,`ins_provinces_code`
,`ins_cities_code`
,`ins_institution_types_code`
,`ins_institution_serial_no`
,`idc`
)
If there are foreign keys referencing the table, the change is a little more involved. (Did you want an additional column added to the foreign keys in the referencing tables?)
It's not entirely clear what you are attempting to achieve.
Yes, you can add the primary key, but in your case, you need to drop pk and then add new pk, otherwise the engine interpretes as you are trying to add multiple pks, the multiple pks are different from composite pk, you can add composite pk, but you can't add multiple pks
alter table xx drop primary key, add primary key(k1, k2, k3);

A Foreign key referencing multiple unique key

I have 3 tables:
class_a
CREATE TABLE class_a (
id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
std_id INT NOT NULL UNIQUE,
name varchar(225) NOT NULL)
class_b
CREATE TABLE class_b (
id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
std_id INT NOT NULL UNIQUE,
name varchar(225) NOT NULL)
sn_number
CREATE TABLE sn_number (
id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
pin INT NOT NULL UNIQUE,
serial VARCHAR(255) NOT NULL UNIQUE,
std_id INT NULL DEFAULT NULL,
FOREIGN KEY(std_id) REFERENCES class_a(std_id)
)
How can I reference unique std_id in class_a and class_b table as a foreign key in sn_number table.
I want to achieve something like ALTER TABLE sn_number ADD FOREIGN KEY(std_id) REFERENCES class_a(std_id), class_b(std_id)
I have tried doing this ALTER TABLE sn_number ADD FOREIGN KEY(std_id) REFERENCES class_a(std_id)
followed by
ALTER TABLE sn_number ADD FOREIGN KEY(std_id) REFERENCES class_b(std_id) on sn_number table but will keep overwriting each other.
I have read these:
Foreign Key Referencing Multiple Tables and
Composite key as foreign key (sql)
But I can't find the solution to the problem am having.
Foreign key must reference only one parent table. This is fundamental to both SQL syntax, and relational theory.
What you can do, is add another table classes or students that contain all std_id , then just reference the FK to it.
Since you haven't explicitly given a constraint name in your FOREIGN KEY declarations, the DBMS makes one up from the table name sn_number. Your problem is that you are thus implicitly declaring the same constraint name each time, so the old info for the name is lost. Just use different explicit constraint names for different cases of table & column list REFERENCES table & column list.
CONSTRAINT fk_sn_number_a FOREIGN KEY(std_id) REFERENCES class_a(std_id)
CONSTRAINT fk_sn_number_b FOREIGN KEY(std_id) REFERENCES class_b(std_id)
Just learn about the basics of Using FOREIGN KEY Constraints.
PS As remarked in a comment, this is a poor design. But contrary to the comment & another answer, your need for two foreign keys from the same table & column list is not a symptom of poor design. But notice that the problems that people usually have with "Foreign Key Referencing Multiple Tables" in questionable designs is that they think that their tables as designed need a foreign key from one place to two places when they don't. Such a design doesn't even involve a foreign key, it just involves something reminiscent of a foreign key.

SQL: Create table with two indexes

I previously created a table using the following SQL code:
CREATE TABLE myTable (
id_A BIGINT NOT NULL,
id_B INT NOT NULL,
some_info varchar(255),
some_info2 varchar(255),
PRIMARY KEY (id_A)
)
In the previous table created, both id_A and id_B would be unique values. I understand that id_A is forced to be unique by the
PRIMARY KEY (id_A) code, which is perfect (which also indexes it), however id_B isn't
Here is where I am confused. id_B will also be unique, however I am not sure how to force it to be unique in the table,and how to make the database create an index for it so that future queries that use SELECT on this table will have good preformance. I know I can't have two PRIMARY KEYS:
PRIMARY KEY (id_A)
PRIMARY KEY (id_B)
How might I go about making an index for id_B as well so that future queries happen efficiently?
You can add a UNIQUE INDEX on the column. While a table can only have one PRIMARY KEY, it can have as many UNIQUE INDEXes as you might need.
ALTER TABLE myTable
ADD UNIQUE INDEX `UI_myTable_idB` (`id_B` );
You can use the MySQL UNIQUE KEY for the column. This will force the values in the id_B column to be unique, but not use it as the primary key column. You can achieve it with this statement:
CREATE TABLE myTable (
id_A BIGINT NOT NULL,
id_B INT NOT NULL,
some_info varchar(255),
some_info2 varchar(255),
PRIMARY KEY (id_A),
UNIQUE KEY (id_b))
This will automatically index the column like you want it to. Primary keys and unique keys in a MySQL table are essentially the same, except a primary key cannot be NULL, and there can be only one primary key column (or combination of primary key columns). There can be any number of unique key columns.

Creating a parent and child table, does child need its own primary id column?

When we create parent-child tables, does the child table need its own primary key, or should the foreign key of the parent be used as the primary key?
Example:
I have a table that stores users, which is defined like:
CREATE TABLE users (
'id' bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT,
'username' varchar(32),
PRIMARY KEY ('id'))
I want to make a second table that stores some more information about a user, like their favorite animals. Should that table have its own 'id' column as well as a separate foreign key for the linked user?:
CREATE TABLE users_extra_info (
'id' bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT,
'fk_user_id' bigint(20) UNSIGNED NOT NULL,
'fav_mammal' varchar(32),
'fav_reptile' varchar(32),
...
PRIMARY KEY ('id'),
KEY 'fk_user_id' ('fk_user_id'))
or do you usually just drop the 'id' column since the foreign key has to be unique?:
CREATE TABLE users_extra_info (
'fk_user_id' bigint(20) UNSIGNED NOT NULL,
'fav_mammal' varchar(32),
'fav_reptile' varchar(32),
...
PRIMARY KEY ('fk_user_id'))
Thanks
As a matter of principle, not related to other tables, each table should have a PRIMARY KEY in order for you to be able to distinguish one row from another. While it's not always necessary to absolutely identify individual rows that is often a requirement.
In the event of a true one-to-one relationship (or a one-to-zero-or-one relationship, which also occurs), because the foreign key is necessarily unique it can also be used as the primary key of the subsidiary table. There is absolutely no reason at all to introduce a second unique column in that case.
However, one-to-one and one-to-zero-or-one relationships are less common than one-to-many relationships. In that more common case, you cannot use only the foreign key columns as the primary key since they are not unique in the child table. In this case you can choose either to introduce an additional integer key or created a composite primary key using the foreign key column(s) and one or more other columns that, together, are guaranteed to be unique.
You have to understand the normalization rules.
Here's the link http://www.studytonight.com/dbms/database-normalization.php.
If you want to put the additional columns to another table, I don't see a reason to have an extra id column. Below is what I would do. Another benefit from this approach is that you ensure 1 to 1 relationship. If you had a separate ID column, you would be able to have many rows in users_extra_info linked to one row in users.
CREATE TABLE users (
id int,
username varchar(32),
PRIMARY KEY (id));
CREATE TABLE users_extra_info (
fk_user_id int,
fav_mammal varchar(32),
fav_reptile varchar(32),
PRIMARY KEY (fk_user_id),
foreign key (fk_user_id) references users(id));
You can also think about cascading deletion.

Primary and foreign key in SQL?

I am not sure about this , but do I need to create foreign key explicitly in the SQL command?
This guy did this:
CREATE TABLE languages (
lang_id TINYINT UNSIGNED NOT NULL AUTO_INCREMENT,
lang VARCHAR(60) NOT NULL,
lang_eng VARCHAR(20) NOT NULL,
PRIMARY KEY (lang_id),
UNIQUE (lang)
);
CREATE TABLE threads (
thread_id INT UNSIGNED NOT NULL AUTO_INCREMENT,
lang_id TINYINT(3) UNSIGNED NOT NULL,
user_id INT UNSIGNED NOT NULL,
subject VARCHAR(150) NOT NULL,
PRIMARY KEY (thread_id),
INDEX (lang_id),
INDEX (user_id)
);
In this case, does it mean that INDEX(lang_id) becomes FOREIGN KEY automatically? I know INDEX makes search go faster, but I don't understand the part about foreign key
I would really appreciate any answer
No. An index is just that... an index on a field. A foreign key tells MySQL that "this particular field MUST have a matching record in that table over there".
MySQL's internal design requires that all fields used as foreign keys be indexed, but modern versions will automatically create that index for you.
The converse is not true, whoever. Adding an index to a field does not turn it into a foreign key - a foreign key definition must also include what the foreign table/field is, and a simple index declaration has none of that information.
For your sample table, you'd need to have
...
INDEX (lang_id),
FOREIGN KEY (lang_id) REFERENCES languages (lang_id),
...
to produce a foreign key.
A foreign key means that the value(s) must exist in the referenced column(s). It is not automatic - you need to write it explicitly.
FOREIGN KEY lang_id REFERENCES languages (lang_id)
No a foreign key has to be explicitly declared
CREATE TABLE threads (
thread_id INT UNSIGNED NOT NULL AUTO_INCREMENT,
lang_id TINYINT(3) UNSIGNED NOT NULL FOREIGN KEY FK_1 REFERENCES languages(lang_id),
user_id INT UNSIGNED NOT NULL,
subject VARCHAR(150) NOT NULL,
PRIMARY KEY (thread_id),
INDEX (lang_id),
INDEX (user_id)
);
What you now have are two tables with primary keys and indexes on those primary key values.
You could stop here if you want but you won't have declared referential integrity enforcing that relationship between laguage and threads tables.
To do that you would explicitly create a foreign key relationship as explained here - http://dev.mysql.com/doc/refman/5.5/en/innodb-foreign-key-constraints.html
The differences are as follows :-
The primary key identifies a record uniquely in a table with multiple rows.
An index is a generic term, where by you can create more than one index for a table, in this case the database creates indexes based on the columns that you specified, so that when you query the appropriate index will kick in and give you results faster.
A foreign key on the other hand says that this column in table b, is the primary column in table A, so that whenever you enter rows into table B the databse will check that the specified column/data exists in table A otherwise it will throw an error.