If I have a table created similarly to the following:
CREATE TABLE MyTable(
id1Part1 INT NOT NULL,
id1Part2 INT NOT NULL,
id2Part1 INT NOT NULL,
id2Part2 INT NOT NULL,
UNIQUE KEY (id1Part1, id1Part2),
UNIQUE KEY (id2Part1, id2Part2)
);
how can I now ask the database to give me the two "unique key" tuples?
(SHOW INDEX doesn't seem to do this.)
I'm not sure if you're looking for something like this
select
constraint_name,
group_concat(column_name order by ordinal_position) as cols
from information_schema.key_column_usage
where table_schema = 'db_name' and table_name = 'table_name'
group by constraint_name
mysql can't give you two primary keys. Check this out:
mysql> CREATE TABLE MyTable(
-> id1Part1 INT NOT NULL,
-> id1Part2 INT NOT NULL,
->
-> id2Part1 INT NOT NULL,
-> id2Part2 INT NOT NULL,
->
-> UNIQUE KEY (id1Part1, id1Part2),
-> UNIQUE KEY (id2Part1, id2Part2)
-> );
Query OK, 0 rows affected (0.17 sec)
mysql> desc mytable;
+----------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------+---------+------+-----+---------+-------+
| id1Part1 | int(11) | NO | PRI | NULL | |
| id1Part2 | int(11) | NO | PRI | NULL | |
| id2Part1 | int(11) | NO | MUL | NULL | |
| id2Part2 | int(11) | NO | | NULL | |
+----------+---------+------+-----+---------+-------+
It shows there is only one primary key.
Related
I'm learning from an online course MySQL using the WampServer and editing code in MySQL Workbench.
Trying to create a table with the following code, the column nome appears to be the primary key from the table, but i'm only using the unique constraint.
When i don't use the unique constraint, the code runs normally and don't give me a primary key.
create table if not exists cursos (
nome varchar(30) not null unique,
descricao text,
carga int unsigned,
totalaulas int unsigned,
ano year default '2016'
) default charset utf8mb4;
Second to this question, when i was trying to drop the constraint primary key i was getting the error Error Code: 1091. Can't DROP 'PRIMARY';
alter table cursos
drop primary key;
So, in resume, i'm trying to use the unique constraint without setting a column has a primary key, and then i'm trying to drop the primary key constraint.
Edit:
When i call describe table i get this, the column nome is defined has primary key whithout i using the constraint.
+------------------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------------+-------------+------+-----+---------+----------------+
| idcurso | int | YES | | NULL | |
| nome | varchar(30) | NO | PRI | NULL | |
+------------------+-------------+------+-----+---------+----------------+
What i'm trying to do is drop the primary key from nome and put on idcurso, but when i use the code
alter table cursos
add primary key idcurso;
I get the error Error Code: 1064. You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line
I tried this on mysql command-line client connected to a MySQL Server 5.5.2. Here is what happens:
mysql> create table if not exists cursos (
-> nome varchar(30) not null unique,
-> descricao text,
-> carga int unsigned,
-> totalaulas int unsigned,
-> ano year default '2016'
-> ) default charset utf8mb4;
Query OK, 0 rows affected (0.08 sec)
mysql>
mysql> desc cursos;
+------------+------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+------------+------------------+------+-----+---------+-------+
| nome | varchar(30) | NO | PRI | NULL | |
| descricao | text | YES | | NULL | |
| carga | int(10) unsigned | YES | | NULL | |
| totalaulas | int(10) unsigned | YES | | NULL | |
| ano | year(4) | YES | | 2016 | |
+------------+------------------+------+-----+---------+-------+
5 rows in set (0.05 sec)
Note that the field nome has a Key as PRI. But, it is only a description and not a fact. If you try to DROP the primary key you will see an error like below:
mysql> alter table cursos drop primary key;
ERROR 1091 (42000): Can't DROP 'PRIMARY'; check that column/key exists
Add a new column and make it a primary key. Note the DESCRIPTION after that.
mysql> alter table cursos add idcurso int primary key;
Query OK, 0 rows affected (0.09 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> desc cursos;
+------------+------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+------------+------------------+------+-----+---------+-------+
| nome | varchar(30) | NO | UNI | NULL | |
| descricao | text | YES | | NULL | |
| carga | int(10) unsigned | YES | | NULL | |
| totalaulas | int(10) unsigned | YES | | NULL | |
| ano | year(4) | YES | | 2016 | |
| idcurso | int(11) | NO | PRI | NULL | |
+------------+------------------+------+-----+---------+-------+
6 rows in set (0.05 sec)
At this point, you can drop the primary key using the syntax: alter table cursos drop primary key;. This will drop the primary key constraint only (but, not the column definition).
If you create yet another column, perhaps guid,
that has a UNIQUE constraint,
then you will be able to do what you wish.
(Not sure why you wish it. Whatever.)
A table can have multiple UNIQUE constraints.
Each table should have a PRIMARY KEY (which will of course be UNIQUE).
It affects physical layout of the rows on disk,
which affects retrieval speed and how the query planner behaves.
If you do not use the PRIMARY keyword, then the first UNIQUE column
will effectively be the primary key.
Put another way, to ALTER the table as you wish,
the backend DB will need to be able to promote
some candidate column so it becomes the new PRIMARY KEY.
Edit: Not sure why this is marked as a duplicate. The error I am getting is different
I am trying to remove a primary key definition but am receiving an error for some reason.
mysql> ALTER TABLE `aux_sponsors` DROP PRIMARY KEY;
ERROR 1091 (42000): Can't DROP 'PRIMARY'; check that column/key exists
mysql> desc aux_sponsors;
+-------------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------------+--------------+------+-----+---------+-------+
| unit | varchar(8) | NO | | MF | |
| code | varchar(32) | NO | PRI | NULL | |
| userid | varchar(32) | NO | | | |
| fullName | varchar(64) | NO | | | |
| department | varchar(255) | NO | | | |
| description | varchar(255) | NO | | NULL | |
+-------------+--------------+------+-----+---------+-------+
6 rows in set (0.01 sec)
Am I doing something wrong here? I simply want no more primary key in this table.
mysql> SHOW CREATE TABLE aux_sponsors;
+--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| aux_sponsors | CREATE TABLE `aux_sponsors` (
`unit` varchar(8) NOT NULL DEFAULT 'MF',
`code` varchar(32) NOT NULL,
`userid` varchar(32) NOT NULL DEFAULT '',
`fullName` varchar(64) NOT NULL DEFAULT '',
`department` varchar(255) NOT NULL DEFAULT '',
`description` varchar(255) NOT NULL,
UNIQUE KEY `code` (`code`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 |
+--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
You don't have a PRIMARY KEY; you have a UNIQUE key. So, you can't do this:
ALTER TABLE `aux_sponsors` DROP PRIMARY KEY
Instead, just do
ALTER TABLE `aux_sponsors` DROP KEY `code`
DESC (a/k/a DESCRIBE) is not a true MySQL feature; according to the docs, "The DESCRIBE statement is provided for compatibility with Oracle."
More from the documentation:
A UNIQUE index may be displayed as PRI if it cannot contain NULL values and there is no PRIMARY KEY in the table. A UNIQUE index may display as MUL if several columns form a composite UNIQUE index; although the combination of the columns is unique, each column can still hold multiple occurrences of a given value.
In your case, the column code is NOT NULL and is the only column in a UNIQUE key, so DESC is showing it as PRI. Because of this type of problem, it's better to use SHOW INDEX to find out the types of keys on a table.
I intend to create a table with two columns (bus_id, bus_passengers). The bus_id is going to be the primary key and will be the foreign key from another created table, which is called "beacap_locationLog", column node_id.
This is the code I wrote (mySQL):
CREATE TABLE Bus(
bus_id INT (10) UNSIGNED NOT NULL,
bus_passengers INT,
PRIMARY KEY (bus_id),
FOREIGN KEY (bus_id) REFERENCES beacap_locationLog(node_id)
);
It's giving me this error:
#1005 - Can't create table 'pei.Bus' (errno: 150)
I don't know what the problem is.
Cannot have the primary + foreign key on the same ! column with the same name
Shoul be like this !
-see i have added a new column !!
CREATE TABLE Bus(
bus_id INT (10) UNSIGNED NOT NULL,
bus_passengers INT,
node_id_fk int,
PRIMARY KEY (bus_id),
FOREIGN KEY (node_id_fk) REFERENCES beacap_locationLog(node_id)
);
also the node_id_fk and node_id must have the same type !
Ok , see full example :
mysql> create table beacap_locationLog(
-> node_id int
-> );
Query OK, 0 rows affected (0.26 sec)
mysql> CREATE TABLE Bus(
-> bus_id INT (10) UNSIGNED NOT NULL,
-> bus_passengers INT,
-> node_id_fk int,
-> PRIMARY KEY (bus_id),
-> FOREIGN KEY (node_id_fk) REFERENCES beacap_locationLog(node_id)
-> );
Query OK, 0 rows affected (0.03 sec)
mysql> desc beacap_locationLog;
+---------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------+---------+------+-----+---------+-------+
| node_id | int(11) | YES | | NULL | |
+---------+---------+------+-----+---------+-------+
1 row in set (0.00 sec)
mysql> desc Bus;
+----------------+------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------------+------------------+------+-----+---------+-------+
| bus_id | int(10) unsigned | NO | PRI | NULL | |
| bus_passengers | int(11) | YES | | NULL | |
| node_id_fk | int(11) | YES | MUL | NULL | |
+----------------+------------------+------+-----+---------+-------+
3 rows in set (0.00 sec)
mysql>
TBL Bus definition
mysql> show create table Bus\G
Table: Bus
Create Table: CREATE TABLE Bus (
bus_id int(10) unsigned NOT NULL,
bus_passengers int(11) default NULL,
node_id_fk int(11) default NULL,
PRIMARY KEY (bus_id),
KEY node_id_fk (node_id_fk)
) ENGINE=MyISAM DEFAULT CHARSET=latin1
1 row in set (0.01 sec)
How to avoid skipping primary ids when inserting records through multiple load statements?
I inserted a file containing 150 records through LOAD statement into a table.
The last primary id in the table after insertion is 150.
Now, when I insert another file with 100 records through the load statement, the primary id assigned to the first record is 251 instead of 151.
How do I avoid these primary id wastage?
More information:
e.g:
mysql> desc test_data;
+------------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+------------------+------+-----+---------+----------------+
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| name | varchar(255) | NO | UNI | NULL | |
| image | varchar(255) | NO | | NULL | |
| created_at | datetime | NO | | NULL | |
+------------+------------------+------+-----+---------+----------------+
4 rows in set (0.00 sec)
My Load statement -
LOAD DATA LOCAL INFILE '~/test_2.dat'
INTO TABLE test_data
FIELDS TERMINATED BY '|'
LINES TERMINATED BY '\n'
set created_at=CURRENT_TIMESTAMP;
Sample data in the file test_2.dat:
|Peter|peter.jpg
|sam|sam.jpg
|radnor|radnor.jpg
|bruce|bruce.jpg
This is the table structure after the load of that file.
mysql> show create table test_data;
| test_data | CREATE TABLE `test_data` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL,
`image` varchar(255) NOT NULL,
`created_at` datetime NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `name` (`name`)
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=latin1 |
Now, the max(id) in this table is 4. But why is the AUTO_INCREMENT value now set to to "8"? Should it not be set to "5"?
You can mark the AUTO_INCREMENT to true on the primary id to skip them during load.
Some more info can help answer better.
I have a mysql table with a compound primary key. The table definition looks like(some column omitted):
CREATE TABLE `wasteitem` (
`categoryid` char(4) NOT NULL,
`classid` char(4) NOT NULL,
`LIflag` int(11) NOT NULL,
PRIMARY KEY (`categoryid`,`classid`)
);
And I want to determine if any of known keys have been used.
If the table have only a simple primary key I can use query like this:
select categoryid from wasteitem where categoryid in ('key1','key2','key3','key4')
Things to be concerned:
The primary key is a compound key.
The known keys in the list might be very long.
This table is very big(26GB)
You could put the keys you're interested in in another (temporary) table, and join.
use it, to look for keys
DESCRIBE wasteitem
that would be something similar:
mysql> describe wasteitem;
+------------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+------------+---------+------+-----+---------+-------+
| categoryid | char(4) | NO | PRI | NULL | |
| classid | char(4) | NO | PRI | NULL | |
| LIflag | int(11) | NO | | NULL | |
+------------+---------+------+-----+---------+-------+
3 rows in set (0.00 sec)