MySQL: #1075 - Incorrect table definition; autoincrement vs another key? - mysql

Here is a table in MySQL 5.3.X+ db:
CREATE TABLE members` (
`id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT,
`memberid` VARCHAR( 30 ) NOT NULL ,
`Time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ,
`firstname` VARCHAR( 50 ) NULL ,
`lastname` VARCHAR( 50 ) NULL ,
UNIQUE (memberid),
PRIMARY KEY (id)
) ENGINE = MYISAM;
Id column is never used in queries, it is just for visual convenience (so it's easy to see how the table grows). Memberid is an actual key, is unique, and memberid is used in queries to identify any member (WHERE memberid='abcde').
My question is: how to keep auto_increment, but make memberid as a primary key? Is that possible?
When I try to create this table with PRIMARY KEY (memberid), I get an error:
1075 - Incorrect table definition; there can be only one auto column and it must be defined as a key
What is the best choice (Hopefully, there is a way to keep id column so performance is good and queries identify any user by memberid, not by id), if the performance is very important (although the disk space is not)?

You can have an auto-Incrementing column that is not the PRIMARY KEY, as long as there is an index (key) on it:
CREATE TABLE members (
id int(11) UNSIGNED NOT NULL AUTO_INCREMENT,
memberid VARCHAR( 30 ) NOT NULL ,
`time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ,
firstname VARCHAR( 50 ) NULL ,
lastname VARCHAR( 50 ) NULL ,
PRIMARY KEY (memberid) ,
KEY (id) --- or: UNIQUE KEY (id)
) ENGINE = MYISAM;

First create table without auto_increment,
CREATE TABLE `members`(
`id` int(11) NOT NULL,
`memberid` VARCHAR( 30 ) NOT NULL ,
`Time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ,
`firstname` VARCHAR( 50 ) NULL ,
`lastname` VARCHAR( 50 ) NULL
PRIMARY KEY (memberid)
) ENGINE = MYISAM;
after set id as index,
ALTER TABLE `members` ADD INDEX(`id`);
after set id as auto_increment,
ALTER TABLE `members` CHANGE `id` `id` INT(11) NOT NULL AUTO_INCREMENT;
Or
CREATE TABLE IF NOT EXISTS `members` (
`id` int(11) NOT NULL,
`memberid` VARCHAR( 30 ) NOT NULL ,
`Time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ,
`firstname` VARCHAR( 50 ) NULL ,
`lastname` VARCHAR( 50 ) NULL,
PRIMARY KEY (`memberid`),
KEY `id` (`id`)
) ENGINE=MYISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;

You can make the id the primary key, and set member_id to NOT NULL UNIQUE. (Which you've done.) Columns that are NOT NULL UNIQUE can be the target of foreign key references, just like a primary key can. (I'm pretty sure that's true of all SQL platforms.)
At the conceptual level, there's no difference between PRIMARY KEY and NOT NULL UNIQUE. At the physical level, this is a MySQL issue; other SQL platforms will let you use a sequence without making it the primary key.
But if performance is really important, you should think twice about widening your table by four bytes per row for that tiny visual convenience. In addition, if you switch to INNODB in order to enforce foreign key constraints, MySQL will use your primary key in a clustered index. Since you're not using your primary key, I imagine that could hurt performance.

I think i understand what the reason of your error.
First you click auto AUTO INCREMENT field then select it as a primary key.
The Right way is First You have to select it as a primary key then you
have to click auto AUTO INCREMENT field.
Very easy.
Thanks

For the above issue, first of all if suppose tables contains more than 1 primary key then first remove all those primary keys and add first AUTO INCREMENT field as primary key then add another required primary keys which is removed earlier. Set AUTO INCREMENT option for required field from the option area.

Identified this solution while reading this thread. Figured id post this for the next guy possibly.
When dealing with Laravel migration file from a package, I Ran into this issue.
My old value was
$table->increments('id');
My new
$table->integer('id')->autoIncrement();

Related

How can I fix the mysql error #1075 - Incorrect table definition? [duplicate]

Here is a table in MySQL 5.3.X+ db:
CREATE TABLE members` (
`id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT,
`memberid` VARCHAR( 30 ) NOT NULL ,
`Time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ,
`firstname` VARCHAR( 50 ) NULL ,
`lastname` VARCHAR( 50 ) NULL ,
UNIQUE (memberid),
PRIMARY KEY (id)
) ENGINE = MYISAM;
Id column is never used in queries, it is just for visual convenience (so it's easy to see how the table grows). Memberid is an actual key, is unique, and memberid is used in queries to identify any member (WHERE memberid='abcde').
My question is: how to keep auto_increment, but make memberid as a primary key? Is that possible?
When I try to create this table with PRIMARY KEY (memberid), I get an error:
1075 - Incorrect table definition; there can be only one auto column and it must be defined as a key
What is the best choice (Hopefully, there is a way to keep id column so performance is good and queries identify any user by memberid, not by id), if the performance is very important (although the disk space is not)?
You can have an auto-Incrementing column that is not the PRIMARY KEY, as long as there is an index (key) on it:
CREATE TABLE members (
id int(11) UNSIGNED NOT NULL AUTO_INCREMENT,
memberid VARCHAR( 30 ) NOT NULL ,
`time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ,
firstname VARCHAR( 50 ) NULL ,
lastname VARCHAR( 50 ) NULL ,
PRIMARY KEY (memberid) ,
KEY (id) --- or: UNIQUE KEY (id)
) ENGINE = MYISAM;
First create table without auto_increment,
CREATE TABLE `members`(
`id` int(11) NOT NULL,
`memberid` VARCHAR( 30 ) NOT NULL ,
`Time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ,
`firstname` VARCHAR( 50 ) NULL ,
`lastname` VARCHAR( 50 ) NULL
PRIMARY KEY (memberid)
) ENGINE = MYISAM;
after set id as index,
ALTER TABLE `members` ADD INDEX(`id`);
after set id as auto_increment,
ALTER TABLE `members` CHANGE `id` `id` INT(11) NOT NULL AUTO_INCREMENT;
Or
CREATE TABLE IF NOT EXISTS `members` (
`id` int(11) NOT NULL,
`memberid` VARCHAR( 30 ) NOT NULL ,
`Time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ,
`firstname` VARCHAR( 50 ) NULL ,
`lastname` VARCHAR( 50 ) NULL,
PRIMARY KEY (`memberid`),
KEY `id` (`id`)
) ENGINE=MYISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
You can make the id the primary key, and set member_id to NOT NULL UNIQUE. (Which you've done.) Columns that are NOT NULL UNIQUE can be the target of foreign key references, just like a primary key can. (I'm pretty sure that's true of all SQL platforms.)
At the conceptual level, there's no difference between PRIMARY KEY and NOT NULL UNIQUE. At the physical level, this is a MySQL issue; other SQL platforms will let you use a sequence without making it the primary key.
But if performance is really important, you should think twice about widening your table by four bytes per row for that tiny visual convenience. In addition, if you switch to INNODB in order to enforce foreign key constraints, MySQL will use your primary key in a clustered index. Since you're not using your primary key, I imagine that could hurt performance.
I think i understand what the reason of your error.
First you click auto AUTO INCREMENT field then select it as a primary key.
The Right way is First You have to select it as a primary key then you
have to click auto AUTO INCREMENT field.
Very easy.
Thanks
For the above issue, first of all if suppose tables contains more than 1 primary key then first remove all those primary keys and add first AUTO INCREMENT field as primary key then add another required primary keys which is removed earlier. Set AUTO INCREMENT option for required field from the option area.
Identified this solution while reading this thread. Figured id post this for the next guy possibly.
When dealing with Laravel migration file from a package, I Ran into this issue.
My old value was
$table->increments('id');
My new
$table->integer('id')->autoIncrement();

Correct structure and index for a Weekly table

I need a table to store text every week for each user.
So I thought two alternatives:
1) Using composite primary key:
CREATE TABLE `WeeklyTxt` (
`Year` YEAR(4) NOT NULL ,
`Week` ENUM('1','2','3','4', ... ,'51','52','53') NOT NULL ,
`UserId` BIGINT NOT NULL ,
`WeekTxt` TEXT NOT NULL,
PRIMARY KEY (`Year`, `Week`, `UserId`)
) ENGINE = InnoDB;
2) Using autoincrement primary key
CREATE TABLE `WeeklyTxt_2` (
`WeekTxtId` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
`Year` YEAR(4) NOT NULL ,
`Week` ENUM('1','2','3','4', ... ,'51','52','53') NOT NULL ,
`UserId` BIGINT NOT NULL ,
`WeekTxt` TEXT NOT NULL
) ENGINE = InnoDB;
I can't figure out what could be the better choice (and why)
It depends of the search in the table that you will usually do!
Tipically I would use a Simple PRIMARY KEY, and I will add another KEY like your KEY: (Year, Week, UserId)

MySQL : able to create a table through MySQL command line, but not able to create via XAMPP

I ran the following query in MySQL command line and the tables were created. But when I ran in XAMPP, I got an error "1005 - Can't create table 'zoneboard.work' (errno: 150)"
My query is :
Create Table user (
id_user INT (50)NOT NULL AUTO_INCREMENT ,
email VARCHAR( 64 ) NOT NULL ,
username VARCHAR( 16 ) NOT NULL ,
password VARCHAR( 32 ) NOT NULL ,
PRIMARY KEY ( id_user )
) ENGINE = InnoDB
CREATE TABLE work (
id_user INT( 50 ) NOT NULL AUTO_INCREMENT ,
task VARCHAR( 50 ) NOT NULL ,
comments VARCHAR( 100 ) NOT NULL ,
assignee VARCHAR( 16 ) NOT NULL ,
priority VARCHAR( 50 ) NOT NULL ,
status VARCHAR( 50 ) NOT NULL ,
dataum1 VARCHAR( 50 ) NOT NULL ,
dataum2 VARCHAR( 50 ) NOT NULL ,
PRIMARY KEY ( id_user ),
FOREIGN KEY(assignee) REFERENCES user(username)
) ENGINE = InnoDB
According to MySQL Documentation : If you are creating a table, it must have the right column names and types, and it must have indexes on the referenced keys, as stated earlier. If these are not satisfied, MySQL returns error number 1005 and refers to error 150 in the error message.
Therefore, try adding an index on your foreign key field username as the following:
CREATE INDEX username_index ON 'user'(username)
You should refer to the primary key of the user table. Integer is faster and it is more secure to use the primary key instead of a none unique value. Imagine you have 2 or more rows with the same username.
CREATE TABLE `work` (
`id_user` int(50) NOT NULL AUTO_INCREMENT,
`task` varchar(50) NOT NULL,
`comments` varchar(100) NOT NULL,
`assignee` int(50) NOT NULL,
`priority` varchar(50) NOT NULL,
`status` varchar(50) NOT NULL,
`dataum1` varchar(50) NOT NULL,
`dataum2` varchar(50) NOT NULL,
PRIMARY KEY (`id_user`),
KEY `assignee` (`assignee`),
CONSTRAINT `assignee` FOREIGN KEY (`assignee`) REFERENCES `user` (`id_user`)
) ENGINE=InnoDB;
CREATE TABLE USER (
id_user INT (50)NOT NULL AUTO_INCREMENT ,
email VARCHAR( 64 ) NOT NULL ,
username VARCHAR( 16 ) NOT NULL ,
PASSWORD VARCHAR( 32 ) NOT NULL ,
PRIMARY KEY ( id_user, username ),
INDEX(username)
) ENGINE = INNODB;
Parent table-user should have an index column(Here username should be indexed).
Refer: http://dev.mysql.com/doc/refman/5.5/en/innodb-foreign-key-constraints.html
InnoDB permits a foreign key to reference any index column or group of columns. However, in the referenced table, there must be an index where the referenced columns are listed as the first columns in the same order.

mysql table with multiple primary key compound constraint

I'm sorry if the title isn't exactly.. useful, but I wasn't sure how to explain my issue in a title.
So basically, I want to create a table like that :
reservation
day
room
id_client
[other_stuff]
For a given day+room, you can get the id_client + everything else. And also for a given id_client + day you can get the room + other stuff.
I don't exactly understand how am I supposed to say that the compound day+room must be unique AND the compound day+id_client must also be unique. I really need both of those constraint in my database.
Anyone has an idea ?
Thanks.
Define one combination an PRIMARY KEY and the other as UNIQUE key:
CREATE TABLE reservation
( day
, room
, id_client
, [other_stuff]
, PRIMARY KEY (day, room)
, UNIQUE KEY (id_client, day)
) ;
or the other way around:
CREATE TABLE reservation
( day
, room
, id_client
, [other_stuff]
, PRIMARY KEY (id_client, day)
, UNIQUE KEY (day, room)
) ;
Or, if you already have another Primary Key, make them both unique:
CREATE TABLE reservation
( reservation_id
, day
, room
, id_client
, [other_stuff]
, PRIMARY KEY (reservation_id)
, UNIQUE KEY (id_client, day)
, UNIQUE KEY (day, room)
) ;
-- in MySQL
drop database if exists mydatabase;
create database mydatabase;
use mydatabase;
drop table if exists client;
create table client
(
id int unsigned not null auto_increment,
name varchar(45) not null,
primary key (id)
)engine=InnoDB default charset=utf8;
drop table if exists room;
create table room
(
id int unsigned not null auto_increment,
label varchar(45) not null,
primary key (id)
)engine=InnoDB default charset=utf8;
drop table if exists reservation;
create table reservation
(
id int unsigned not null auto_increment,
id_room int unsigned,
id_client int unsigned,
day date,
unique(day, id_room),
unique(day, id_client),
foreign key (id_room) references room(id),
foreign key (id_client) references client(id),
primary key (id)
)engine=InnoDB default charset=utf8;
There are two ways of looking at this... are the unique constraints you mention mutually exclusive? Meaning, can one exist without the other?
Logic dictates that a room can be booked to one day at a time, regardless of client. Unless multiple clients can share the same room. So I will give you two alternatives.
# If room can be booked to multiple clients
CREATE TABLE `reservation` (
`id` int(11) unsigned not null auto_increment,
`day` varchar(25) not null,
`room` int(5) unsigned not null,
`id_client` int(11) unsigned not null,
PRIMARY KEY (`id`),
UNIQUE KEY (`room`, `day`),
UNIQUE KEY (`room`, `id_client`),
)ENGINE=InnoDB DEFAULT CHARSET=utf8;
# Room can only be booked to one client for a given day
CREATE TABLE `reservation` (
`id` int(11) unsigned not null auto_increment,
`day` varchar(25) not null,
`room` int(5) unsigned not null,
`id_client` int(11) unsigned not null,
PRIMARY KEY (`id`),
UNIQUE KEY (`room`, `day`)
)ENGINE=InnoDB DEFAULT CHARSET=utf8;
Also, I would use a separate primary key column, otherwise your updates will be more complex, for example:
UPDATE `reservation` SET `other_stuff` = 'some value' WHERE `day` = 'Friday' AND `room` = 123;
# Vs
UPDATE `reservation` SET `other_stuff` = 'some value' WHERE `id` = 1;

Can't create mysql table with foreign key

I am getting errno 150 when I try to create the following two tables.
CREATE TABLE `mydatabase`.`userstatus`(
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT ,
`name` VARCHAR(50) NOT NULL ,
`description` VARCHAR(255) ,
PRIMARY KEY (`id`)
);
CREATE TABLE `mydatabase`.users(
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT ,
`email` VARCHAR(200) NOT NULL ,
`username` VARCHAR(20) NOT NULL DEFAULT 'Unknown' ,
`userstatusid` INT UNSIGNED NOT NULL DEFAULT 2 ,
`datemodified` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`datecreated` DATETIME DEFAULT 0 NOT NULL ,
PRIMARY KEY (`id`),
UNIQUE (username),
UNIQUE (email),
INDEX userstatusid_index (userstatusid),
CONSTRAINT fk_users_userstatus FOREIGN KEY (userstatusid) REFERENCES userstatus(id)
ON DELETE SET NULL
ON UPDATE CASCADE
) ENGINE=INNODB ROW_FORMAT=DEFAULT ;
What's causing the error and how do I fix it?
I put on delete set null but the column has been defined as not null. I was focusing too much attention to the types which usually causes the errno 150.
Maybe you could try set a Unique key on userstatusid.
Sometimes that may help.
You can try SHOW INNODB STATUS which will show the last InnoDB error (e.g. foreign key constraint definition problems).
(Otherwise you have to just guess based on the error number and limited information which the error from the statement provides, which isn't ideal.)