Why won't my SQL table creation work in Codio? - mysql

I am trying to complete my homework but am getting an error message saying that the table I'm creating doesn't match what is expected to be input. Here is what the table is supposed to contain:
+-----------+-----------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------+-----------------+------+-----+---------+----------------+
| id | int(3) unsigned | NO | PRI | NULL | auto_increment |
| room_num | int(4) unsigned | NO | UNI | NULL | |
| course_id | int(3) unsigned | YES | MUL | NULL | |
+-----------+-----------------+------+-----+---------+----------------+
The code I am entering to try and achieve this is:
CREATE TABLE college.classrooms (
id INT(3) UNSIGNED NOT NULL AUTO_INCREMENT,
room_num INT(4) UNSIGNED NOT NULL UNIQUE KEY,
course_id INT(3) UNSIGNED DEFAULT NULL,
PRIMARY KEY (id),
FOREIGN KEY (course_id) REFERENCES college.courses(id)
) AUTO_INCREMENT = 1;
My school uses Codio and it auto checks the table to see if it's correct and that is the error message I'm getting:
[Error]: Create a 'classrooms' table with the requested structure. Reset the database and try again
What am I missing from my code to make this work? I've already created the table it is referencing (courses).

Is it probably failing on the FOREIGN KEY REFERENCES context? You are trying to create a table that is EXPECTING the course_id to be found in a secondary table "college.courses". If the college.courses table is not created yet, this table could never reference it.
Make sure the COURSES table is created FIRST

CREATE TABLE classrooms
(
id INT(3) unsigned primary key NOT NULL AUTO_INCREMENT,
room_num INT(4) unsigned NOT NULL UNIQUE,
course_id INT(3) unsigned DEFAULT NULL,
FOREIGN KEY (course_id) REFERENCES college.courses(id)
)
AUTO_INCREMENT = 1;

Related

Adding a FOREIGN KEY but says the column does not exists when it does?

I have created two tables
EMPLOYEE
CREATE TABLE employee (
emp_id INT AUTO_INCREMENT NOT NULL,
first_name VARCHAR(20) NOT NULL,
last_name VARCHAR(20) NOT NULL,
address VARCHAR(20) NOT NULL,
PRIMARY KEY (emp_id)
);
TEAM
CREATE TABLE team (
team_id INT AUTO_INCREMENT NOT NULL,
name VARCHAR(20),
manager_id INT (20),
PRIMARY KEY (team_id)
);
I am trying to add a add a foreign key:
ALTER TABLE employee ADD FOREIGN KEY (manager_id) REFERENCES team(manager_id);
It is giving me an error telling me that the column does not exist
ERROR 1072 (42000): Key column 'manager_id' doesn't exist in table
But it does show when I Describe team
| Field | Type | Null | Key | Default | Extra |
+------------+-------------+------+-----+---------+----------------+
| team_id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(20) | YES | | NULL | |
| manager_id | int(20) | YES | | NULL | |
+------------+-------------+------+-----+---------+----------------+
Column manager_id does not exists in table employee.
Something like this would be more meaningful:
ALTER TABLE team ADD FOREIGN KEY (manager_id) REFERENCES employee(emp_id);
Possibly, you also build a table to represent the relationship between employees and teams. As of now, nothing in your schema can be used to relate an employee to one or several teams.

indexes and constraints not created in CREATE TABLE statement

I am using MySQL/MariaDB, and I create an employees table:
CREATE TABLE employees(
id INT AUTO_INCREMENT,
name VARCHAR(40) NOT NULL,
description VARCHAR(50) DEFAULT 'No Description',
random_assignment_id INT UNIQUE,
birth_date DATE,
salary DECIMAL(5,2),
supervisor_id INT,
branch_id INT NOT NULL,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT random_assignment_check CHECK (LENGTH(random_assignment_id) = 5),
INDEX(random_assignment_id, supervisor_id, branch_id),
PRIMARY KEY(id)
)
Then I confirm the table is created as expected:
SHOW CREATE TABLE employees\G;
*************************** 1. row ***************************
Table: employees
Create Table: CREATE TABLE `employees` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(40) NOT NULL,
`description` varchar(50) DEFAULT 'No Description',
`random_assignment_id` int(11) DEFAULT NULL,
`birth_date` date DEFAULT NULL,
`salary` decimal(5,2) DEFAULT NULL,
`supervisor_id` int(11) DEFAULT NULL,
`branch_id` int(11) NOT NULL,
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `random_assignment_id` (`random_assignment_id`),
KEY `random_assignment_id_2` (`random_assignment_id`,`supervisor_id`,`branch_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.01 sec)
I don't see the random_assignment_check constraint listed, and I expected it to index random_assignment_id, supervisor_id and branch_id, but it does not:
DESCRIBE employees;
+----------------------+--------------+------+-----+-------------------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------------------+--------------+------+-----+-------------------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(40) | NO | | NULL | |
| description | varchar(50) | YES | | No Description | |
| random_assignment_id | int(11) | YES | UNI | NULL | |
| birth_date | date | YES | | NULL | |
| salary | decimal(5,2) | YES | | NULL | |
| supervisor_id | int(11) | YES | | NULL | |
| branch_id | int(11) | NO | | NULL | |
| created_at | timestamp | NO | | CURRENT_TIMESTAMP | |
| updated_at | timestamp | NO | | CURRENT_TIMESTAMP | |
+----------------------+--------------+------+-----+-------------------+----------------+
There are no MUL flags under key.
Note that I read MariaDB now supports Constraints; according to homebrew, I am using:
brew info mariadb
mariadb: stable 10.3.12 (bottled)
Drop-in replacement for MySQL
What am I doing wrong?
MySQL treats KEY as a synonym for INDEX. Your index INDEX(random_assignment_id, supervisor_id, branch_id) became KEY random_assignment_id_2 (random_assignment_id,supervisor_id,branch_id). The index name was generated by MySQL, but logically they're the same index.
When I tested your CREATE TABLE statement and then use DESC to display it, I also see no MUL indicators. This fits the documentation:
If Key is MUL, the column is the first column of a nonunique index in which multiple occurrences of a given value are permitted within the column.
So in your output, the Key field for random_assignment_id is UNI because it's a unique key, in addition to part of a multi-column key.
MySQL doesn't support CHECK constraints. It parses them, then ignores them. They are not stored with your table, and subsequently using SHOW CREATE TABLE doesn't show them.
MariaDB has implemented CHECK constraints in 10.2.1 according to https://mariadb.com/kb/en/library/constraint/#check-constraints (I don't use MariaDB, so I'll trust their doc).
It's not clear from your question if you tested your CHECK constraint on MySQL Community Edition or MariaDB. CHECK constraint will not be saved on MySQL, and on MariaDB it seems okay per the doc, but I have never tested it.
We should all stop thinking of MariaDB a drop-in replacement for MySQL. The two products have been diverging for nearly 10 years, and they can no longer be assumed to be compatible.

SQL how to create a table with a unique key?

Create a courses table with this definition (try using a multi-line SQL statement):
+---------+---------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------+---------------------+------+-----+---------+----------------+
| id | int(3) unsigned | NO | PRI | NULL | auto_increment |
| title | varchar(255) | NO | UNI | NULL | |
| credits | tinyint(2) unsigned | NO | | 1 | |
I keep getting an error when trying to create the table, this is what I have:
CREATE TABLE courses
(
id int(3) unsigned NOT NULL AUTO_INCREMENT,
title varchar(255) NOT NULL UNIQUE,
credits tinyint(2) unsigned NOT NULL DEFAULT 1;
Error:
Incorrect table definition; there can be only one auto column and it must be defined as a key
Correct SQL sentence:
CREATE TABLE courses (
id int(3) unsigned primary key NOT NULL AUTO_INCREMENT,
title varchar(255) NOT NULL UNIQUE,
credits tinyint(2) unsigned NOT NULL DEFAULT 1);
Your sentence loses primary key.
Two mistakes:
The auto_increment column must be a primary key in MySQL.
You need to end the SQL sentence with a ).
This SQL works:
CREATE TABLE courses (
id int(3) unsigned primary key NOT NULL AUTO_INCREMENT,
title varchar(255) NOT NULL UNIQUE,
credits tinyint(2) unsigned NOT NULL DEFAULT 1
);

Altering existing unique constraint

I have a table that was defined like this:
CREATE TABLE `Message` (
`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY,
`user_id` integer NOT NULL,
`user_to` integer NOT NULL,
`top_num` integer NOT NULL,
`priority` smallint NOT NULL,
`error` varchar(120) NOT NULL,
UNIQUE (`user_id`, `user_to`, `top_num`)
);
Later, I added another column to it, msg_type, like this:
ALTER TABLE Message ADD COLUMN msg_type SMALLINT(6) NOT NULL DEFAULT 0;
However, I have come to realize that I need to change my original UNIQUE constraint to include msg_type. I tried running
ALTER TABLE Message
ADD UNIQUE INDEX (`user_id`, `user_to`, `top_num`, `msg_type`);
but INSERTs into my table still fail, and the error message indicates that that is because the old uniqueness constraint fails.
When I call describe Messages in mysql I see the following:
+-----------------+----------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------------+----------------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| user_id | int(11) | NO | MUL | NULL | |
| user_to | int(11) | NO | MUL | NULL | |
| top_num | int(11) | NO | MUL | NULL | |
| priority | smallint(6) | NO | | NULL | |
| error | varchar(120) | NO | | NULL | |
| msg_type | smallint(6) | NO | | 0 | |
+-----------------+----------------------+------+-----+---------+----------------+
which makes it seem like msg_type really isn't part of the constraint... How can I alter the constraint that the table was defined with, short of recreating the table?
As in previous answer to change foreign key constraint use steps:
Step 1: Drop old constraint:
ALTER TABLE `Message` DROP INDEX `user_id`;
Step 2: Add new:
ALTER TABLE `Message` ADD UNIQUE INDEX (
`user_id`,
`user_to`,
`top_num`,
`msg_type`);
Use SHOW CREATE TABLE to know name of constraint:
mysql> SHOW CREATE TABLE `Message` ;
| Message | CREATE TABLE `Message` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) NOT NULL,
`user_to` int(11) NOT NULL,
`top_num` int(11) NOT NULL,
`priority` smallint(6) NOT NULL,
`error` varchar(120) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `user_id` (`user_id`,`user_to`,`top_num`)
-- ^^^^^^^^^ name
) ENGINE=InnoDB DEFAULT CHARSET=latin1 |
If you checks:
mysql> SHOW INDEX FROM `Message`;
Key_name is user_id that is first argument in UNIQUE (user_id ....
Suppose if you write:
ALTER TABLE `Message` ADD UNIQUE INDEX (
`user_to`,
`user_id`,
`top_num`,
`msg_type`);
Then you have to drop using user_to as:
ALTER TABLE `Message` DROP INDEX `user_to`;
This is because you are adding unique index. Please first drop unique index and then add unique constraint.
-- you have to drop each index one by one.
ALTER TABLE Message DROP UNIQUE INDEX user_id;
and now add unique constraint.
ALTER TABLE Message ADD CONSTRAINT uc_message UNIQUE (`user_id`, `user_to`, `top_num`, `msg_type`);
This is because you haven't deleted the first unique constraint you have created. Right now, you have two unique constraints on your table.
To delete a unique constraint, have a look at this post
Dropping Unique constraint from MySQL table
This is because you are adding unique index. Please first drop unique index and then add unique constraint.
DROP INDEX index_name ON table_name
and now add unique constraint.
ALTER TABLE Message
ADD CONSTRAINT uc_message UNIQUE ((`user_id`, `user_to`, `top_num`, `msg_type`);)

MySql query taking too long - django on webfaction

I use django on webfaction, and I've got a "MySql query taking too long" message,
the sql is
SELECT (1) AS `a` FROM `main_userprofile` WHERE `main_userprofile`.`id` = 98
This is a rather simple sql, why the query taken too long?
here it is the 'create table':
main_userprofile | CREATE TABLE `main_userprofile` (
`id` int(11) NOT NULL auto_increment,
`user_id` int(11) NOT NULL,
`sex` smallint(6) NOT NULL,
`active_number` varchar(64) NOT NULL,
`phone_number` varchar(32) NOT NULL,
`work_number` varchar(32) NOT NULL,
...
...
PRIMARY KEY (`id`),
UNIQUE KEY `user_id` (`user_id`)
) ENGINE=MyISAM AUTO_INCREMENT=1652 DEFAULT CHARSET=utf8 |
the id is the primary key
the explain:
explain SELECT (1) AS `a` FROM `main_userprofile` WHERE `main_userprofile`.`id` = 98;
+----+-------------+------------------+-------+---------------+---------+---------+-------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+------------------+-------+---------------+---------+---------+-------+------+-------------+
| 1 | SIMPLE | main_userprofile | const | PRIMARY | PRIMARY | 4 | const | 1 | Using index |
+----+-------------+------------------+-------+---------------+---------+---------+-------+------+-------------+
Seems like id is not indexed, isn't it. Is id the primary key of your table? Could you post the result of SHOW CREATE TABLE main_userprofile;?