MySQL: Name primary key in CREATE TABLE statement - sql

How do I set the name of a primary key when creating a table?
For example here I'm trying to create a primary key with the name 'id', but this is invalid SQL. Can you tell me the correct way to do this?
CREATE TABLE IF NOT EXISTS `default_test`
(
`default_test`.`id` SMALLINT NOT NULL AUTO_INCREMENT PRIMARY KEY `id`,
`default_test`.`name` LONGTEXT NOT NULL
)
Clarification
I'd like to specify the name of the primary key - rather than the default name of "PRIMARY" I'd like it to be called "id" or perhaps "primary_id", so if I were to later run SHOW INDEXES FROM default_test, the Key_name will be something I have specified.

Alternatively and more widely supported:
CREATE TABLE IF NOT EXISTS `default_test` (
`default_test`.`id` SMALLINT NOT NULL AUTO_INCREMENT,
`default_test`.`name` LONGTEXT NOT NULL,
PRIMARY KEY (`id`)
)
UPDATE
Based on the clarification, you could replace the last definition above with the following if you are to specify the index name:
CONSTRAINT `pk_id` PRIMARY KEY (`id`)

http://dev.mysql.com/doc/refman/5.1/en/create-table.html
[...] In MySQL, the name of a PRIMARY KEY is PRIMARY. [...]
CREATE TABLE IF NOT EXISTS `default_test` (
`default_test`.`id` SMALLINT NOT NULL AUTO_INCREMENT,
`default_test`.`name` LONGTEXT NOT NULL,
PRIMARY KEY (`id`)
)

You shouldn't specify the column name when you specify the primary key column name directly inline with the column definition, so:
CREATE TABLE IF NOT EXISTS `default_test` (
`default_test`.`id` SMALLINT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`default_test`.`name` LONGTEXT NOT NULL
);
Alternativly you could do:
CREATE TABLE IF NOT EXISTS `default_test` (
`default_test`.`id` SMALLINT NOT NULL AUTO_INCREMENT ,
`default_test`.`name` LONGTEXT NOT NULL ,
PRIMARY KEY `default_test_id_pkey` (`id`)
);

You don't have to specify the column name again, because you already specified it as part of the current field definition - just say PRIMARY KEY.
CREATE TABLE IF NOT EXISTS `default_test` (
`id` SMALLINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
`name` LONGTEXT NOT NULL
)
Alternatively, you can specify it separately later:
CREATE TABLE IF NOT EXISTS `default_test` (
`id` SMALLINT NOT NULL AUTO_INCREMENT,
`name` LONGTEXT NOT NULL,
PRIMARY KEY(`id`)
)

Related

Why does it keep giving me te same errors?

So I wanted to put a sql file in a database (es_extended.sql) and it keeps giving me errors like: duplicate column name name etc. and
SQL error (1050): Table 'items' already exists
I have tried to change the names of columns and all but it keeps giving the same errors.
here is the code:
ALTER TABLE `users`
ADD COLUMN `money` VARCHAR(50) DEFAULT NULL,
ADD COLUMN `name` VARCHAR(50) NULL DEFAULT '' AFTER `money`,
ADD COLUMN `skin` LONGTEXT NULL AFTER `name`,
ADD COLUMN `job` VARCHAR(50) NULL DEFAULT 'unemployed' AFTER `skin`,
ADD COLUMN `job_grade` INT NULL DEFAULT 0 AFTER `job`,
ADD COLUMN `loadout` LONGTEXT NULL AFTER `job_grade`,
ADD COLUMN `position` VARCHAR(36) NULL AFTER `loadout`
;
CREATE TABLE `items` (
`name` varchar(50) NOT NULL,
`label` varchar(50) NOT NULL,
`limit` int(11) NOT NULL DEFAULT '-1',
`rare` int(11) NOT NULL DEFAULT '0',
`can_remove` int(11) NOT NULL DEFAULT '1',
PRIMARY KEY (`name`)
);
CREATE TABLE `job_grades` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`job_name` varchar(50) DEFAULT NULL,
`grade` int(11) NOT NULL,
`name` varchar(50) NOT NULL,
`label` varchar(50) NOT NULL,
`salary` int(11) NOT NULL,
`skin_male` longtext NOT NULL,
`skin_female` longtext NOT NULL,
PRIMARY KEY (`id`)
);
INSERT INTO `job_grades` VALUES (1,'unemployed',0,'unemployed','Unemployed',200,'{}','{}');
CREATE TABLE `jobs` (
`name` varchar(50) NOT NULL,
`label` varchar(50) DEFAULT NULL,
PRIMARY KEY (`name`)
;
INSERT INTO `jobs` VALUES ('unemployed','Unemployed');
CREATE TABLE `user_accounts` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`identifier` varchar(22) NOT NULL,
`name` varchar(50) NOT NULL,
`money` double NOT NULL DEFAULT '0',
PRIMARY KEY (`id`)
);
CREATE TABLE `user_inventory` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`identifier` varchar(22) NOT NULL,
`item` varchar(50) NOT NULL,
`count` int(11) NOT NULL,
PRIMARY KEY (`id`)
);
Sql databases are a way to implement the persistence layer: data that should be kept permanently or at least independently from sessions.
The error you're getting: SQL error (1050): Table 'items' already exists means that you've already created a table with the same name you're using to try and create a new table.
You do not need to recreate the table each time you try to add data to it. The table is persistent as long as you do not DROP (delete) it or the database it belongs to.
If you want to recreate the table (either because you need to change its schema or because you want to start over), you can run the command DROP TABLE items which will delete the table and all data in the table.
After dropping, you can run the CREATE TABLE items... command again.
If you don't want to delete the table, you can just run the INSERT INTO items... command to add data to the existing table.
The SQL Error (xxxx): duplicate column name 'name' error means you are trying to add a column that already exists in the table. If the users table already has a column called name, then you cannot run the command ALTER TABLE users ADD COLUMN 'name'... without an error.
If the column doesn't meet your needs anymore, you can use ALTER TABLE users ALTER COLUMN 'name'... to change the schema for the column.

PostgreSQL UNIQUE constraint and REFERENCES

Let's say I have a table tree and a table special_tree
CREATE TABLE tree VALUES (name VARCHAR(32) UNIQUE NOT NULL PRIMARY KEY,
type VARCHAR(32) NOT NULL);
CREATE TABLE special_tree VALUES (name NOT NULL REFERENCES tree(name),
treat_date DATE,
id INT NOT NULL PRIMARY KEY);
So I have a table containing a list of trees with unique names BUT I want to say that a tree can have multiple 'treat_date' (for various reasons).
Since tree(name) is unique I can't add 2 same name in special_tree.
Is the only solution is to remove unique from tree and then add everywhere i handle the tree table an IF statement to check if name isn't already there? (IF EXISTS (SELECT name FROM tree where tree.name = ...))
If you consider the column name of the table tree it doesn't mean that all referenced columns also should have unique values. Take a look at this example
the best solution for this is (for MySQL):
CREATE TABLE tree VALUES (
id_t int(11) NOT NULL auto_increment,
name VARCHAR(32) NOT NULL,
type VARCHAR(32) NOT NULL,
CONSTRAINT tree_pk PRIMARY KEY (id_t));
CREATE TABLE special_tree VALUES (
id_st int(11) NOT NULL auto_increment,
id_t NOT NULL REFERENCES tree(id_t),
treat_date DATE,
CONSTRAINT special_tree_pk PRIMARY KEY (id_st));
for PostgreSQL:
CREATE TABLE tree VALUES (
id_t serial primary key,
name VARCHAR(32) NOT NULL,
type VARCHAR(32) NOT NULL);
CREATE TABLE special_tree VALUES (
id_st serial primary key,
id_t NOT NULL REFERENCES tree(id_t),
treat_date DATE);

Creating relationship between primary key to composite key -- phpMyAdmin

I am trying to create a relation between a field 'fldEmpID' in my Employees table to a foreign composite key which consists of fldEmpID and fldEventID but it is not allowing the relation to be created. I don't understand why this relation won't work, I was able to create a similar relation between fldEventID from an Events to the composite key. Both fldEmpID fields in each table are int(11). What can I do to create this relation?
The following are the two tables... (I would like to keep the composite key on the table to the right as it helps to prevent duplicates and works well)
It seems to work as expected for me. I created the tables and used the Designer tab to create the relation (by selecting the "Create relation" icon, then clicking fldEmpId in table a, and finally selecting fldEmpID in table b).
For reference, I pasted below the structure of my table (which includes the keys and restraints)
CREATE TABLE IF NOT EXISTS `a` (
`fldEmpId` int(11) NOT NULL,
`fldEmpName` varchar(50) NOT NULL,
`fldEmail` varchar(50) NOT NULL,
`fldPassHash` varchar(50) NOT NULL,
`fldPassSalt` varchar(50) NOT NULL,
`fldAdmin` enum('1','2') NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
CREATE TABLE IF NOT EXISTS `b` (
`fldEmpID` int(11) NOT NULL,
`fldEventID` bigint(20) unsigned NOT NULL,
`fldDTAdded` datetime NOT NULL,
`fldDTRemoved` datetime NOT NULL,
`fldPosition` enum('0','1','2','3','4','5') NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
ALTER TABLE `a`
ADD PRIMARY KEY (`fldEmpId`);
ALTER TABLE `b`
ADD PRIMARY KEY (`fldEmpID`), ADD UNIQUE KEY `fldEventID` (`fldEventID`);
ALTER TABLE `a`
MODIFY `fldEmpId` int(11) NOT NULL AUTO_INCREMENT;
ALTER TABLE `b`
ADD CONSTRAINT `fk` FOREIGN KEY (`fldEmpID`) REFERENCES `a` (`fldEmpId`);

How i can make tables for the given many to many related classes?

I have a scenario of of three classes .I am planning to make the database for it .The relationship between them is :
1 customer is related with many items and many dv-vouchers.
1 item is related with many customer and many dv-vouchers.
1 dv-vouchers is related with 1 customer and many items .
public Customer
{
int cust_id;
list<items> items;
list<dvouchers> dvouchers;
}
public items
{
int itm_id;
list<Customer> customers;
list<dvouchers> dvouchers;
}
public dvouchers
{
int dv_id;
Customer customer;
list<items> items;
}
First of all what can be the design for database tables for above classes, fk_constraints and relationship tables ?
Second Do I need to perform Insert and Update operation on both the relationship tables along db table ? Please Help .
1.
You need two tables Customer_Item and Item_Dvoucher for relationship many-to-many and field cust_id in table Dvoucher for one-to-one relationship.
2.
You need to insert or update data in base tables Customer, Item and Dvoucher. Then you need to add or remove relationship in table Customer_Item and Items_Dvoucher. Also fill field cust_id in table Dvoucher.
Generated in mysql:
CREATE TABLE `Customer` (
`cust_id` INT(11) NOT NULL AUTO_INCREMENT,
`name` VARCHAR(255) DEFAULT NULL,
PRIMARY KEY (`cust_id`)
)
CREATE TABLE `Dvoucher` (
`dv_id` INT(11) NOT NULL AUTO_INCREMENT,
`name` VARCHAR(255) DEFAULT NULL,
`cust_id` INT(11) DEFAULT NULL,
PRIMARY KEY (`dv_id`),
KEY `cust_id` (`cust_id`),
CONSTRAINT `Dvoucher_ibfk_1` FOREIGN KEY (`cust_id`) REFERENCES `Customer` (`cust_id`)
)
CREATE TABLE `Item` (
`item_id` INT(11) NOT NULL AUTO_INCREMENT,
`name` VARCHAR(255) DEFAULT NULL,
PRIMARY KEY (`item_id`)
)
CREATE TABLE `Customer_Item` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`cust_id` INT(11) DEFAULT NULL,
`item_id` INT(11) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `cust_id` (`cust_id`),
KEY `item_id` (`item_id`),
CONSTRAINT `Customer_Item_ibfk_1` FOREIGN KEY (`cust_id`) REFERENCES `Customer` (`cust_id`),
CONSTRAINT `Customer_Item_ibfk_2` FOREIGN KEY (`item_id`) REFERENCES `Item` (`item_id`)
)
CREATE TABLE `Item_Dvoucher` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`item_id` INT(11) DEFAULT NULL,
`dv_id` INT(11) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `item_id` (`item_id`),
KEY `dv_id` (`dv_id`),
CONSTRAINT `Item_Dvoucher_ibfk_1` FOREIGN KEY (`item_id`) REFERENCES `Item` (`item_id`),
CONSTRAINT `Item_Dvoucher_ibfk_2` FOREIGN KEY (`dv_id`) REFERENCES `Dvoucher` (`dv_id`)
)
In SQLite:
CREATE TABLE customer(cust_id INTEGER PRIMARY KEY, ...);
CREATE TABLE item(itm_id INTEGER PRIMARY KEY, ...);
CREATE TABLE dvoucher(dv_id INTEGER PRIMARY KEY, cust_id REFERENCES customer(cust_id), ...);
CREATE TABLE dvoucher_item(dv_id REFERENCES dvoucher(dv_id), itm_id REFERENCES item(itm_id));
CREATE TABLE customer_item(cust_id INTEGER PRIMARY KEY, itm_id REFERENCES item(itm_id));
As #Andrei solution to MySQL, using dvoucher.cust_id to link dvoucher to costumer, and tables dvoucher_item and customer_item to many to many links.

Two n x m relationships with the same table in mysql

I want to create a database in which there's an n x m relationship between the table drug and the table article and an n x m relationship between the table target and the table article.
I get the error: Cannot delete or update a parent row: a foreign key constraint fails
What do I have to change in my code?
DROP TABLE IF EXISTS `textmine`.`article`;
CREATE TABLE `textmine`.`article` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'Pubmed ID',
`abstract` blob NOT NULL,
`authors` blob NOT NULL,
`journal` varchar(256) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
DROP TABLE IF EXISTS `textmine`.`drugs`;
CREATE TABLE `textmine`.`drugs` (
`id` int(10) unsigned NOT NULL COMMENT 'This ID is taken from the biosemantics dictionary',
`primaryName` varchar(256) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
DROP TABLE IF EXISTS `textmine`.`targets`;
CREATE TABLE `textmine`.`targets` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`primaryName` varchar(256) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
DROP TABLE IF EXISTS `textmine`.`containstarget`;
CREATE TABLE `textmine`.`containstarget` (
`targetid` int(10) unsigned NOT NULL,
`articleid` int(10) unsigned NOT NULL,
KEY `target` (`targetid`),
KEY `article` (`articleid`),
CONSTRAINT `article` FOREIGN KEY (`articleid`) REFERENCES `article` (`id`),
CONSTRAINT `target` FOREIGN KEY (`targetid`) REFERENCES `targets` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
DROP TABLE IF EXISTS `textmine`.`contiansdrug`;
CREATE TABLE `textmine`.`contiansdrug` (
`drugid` int(10) unsigned NOT NULL,
`articleid` int(10) unsigned NOT NULL,
KEY `drug` (`drugid`),
KEY `article` (`articleid`),
CONSTRAINT `article` FOREIGN KEY (`articleid`) REFERENCES `article` (`id`),
CONSTRAINT `drug` FOREIGN KEY (`drugid`) REFERENCES `drugs` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
You are trying to create tables out of order.
For example you are trying to create contiansdrug table which refers to table drugs before drugs table.
Remember that any SQL, even DDL, tries to leave database in consistent state.
I would recommend putting the commands in proper order. Alternatively you have options to turn off the checks temporarily and run the creation scrip inside transaction, see the instructions here
Relevant section is
SET AUTOCOMMIT = 0;
SET FOREIGN_KEY_CHECKS=0;
.. your script..
SET FOREIGN_KEY_CHECKS = 1;
COMMIT;
SET AUTOCOMMIT = 1;
EDIT:
OK, try not to have same names for constraints. Reading the fine manual enlightens:
If the CONSTRAINT symbol clause is
given, the symbol value must be unique
in the database. If the clause is not
given, InnoDB creates the name
automatically.
EDIT2:
To spell it out, you have duplicate constrain symbol article, rename it and all will be fine.
Standard practice is if you name your constrains to use names that describe what is related, for example containsdrug_acticelid_article_id (firsttablename_column_secondtablename_column) would be unique and descriptive.
I solved the problem by not declaring the Foreign Key inside of MySql but simply declaring them as ints.