First Database Schema - Producing an error - mysql

This is my schema:
CREATE TABLE item (
id integer NOT NULL PRIMARY KEY AUTO_INCREMENT,
title varchar(60) NOT NULL,
description varchar(900) NOT NULL,
company_id integer NOT NULL REFERENCES company (id),
date datetime NOT NULL,
source_id integer NOT NULL REFERENCES source (id),
link varchar(255) NOT NULL,
location_id integer NOT NULL REFERENCES location (id)
);
CREATE TABLE location (
id integer NOT NULL PRIMARY KEY AUTO_INCREMENT,
name varchar(255) NOT NULL,
coordinate varchar(255) NOT NULL,
location_id integer NOT NULL REFERENCES country (id)
);
CREATE TABLE country (
id integer NOT NULL PRIMARY KEY AUTO_INCREMENT,
name varchar(255) NOT NULL
);
CREATE TABLE company (
id integer NOT NULL PRIMARY KEY AUTO_INCREMENT,
name varchar(60) NOT NULL,
);
CREATE TABLE source (
id integer NOT NULL PRIMARY KEY AUTO_INCREMENT,
name varchar(60) NOT NULL,
);
It is telling me that there is invalid syntax on line four on http://sqlfiddle.com when I put it in and click build schema. I can see no error, can anyone shed some light please?
Also if I have done anything poorly or made any bad decisions please let me know.

You have 2 faulty commas. One at the end of "CREATE TABLE company", "CREATE TABLE source".
And create country before location.
CREATE TABLE company (
id SERIAL PRIMARY KEY,
name varchar(60) NOT NULL
);
CREATE TABLE country (
id SERIAL PRIMARY KEY,
name varchar(255) NOT NULL
);
CREATE TABLE location (
id SERIAL PRIMARY KEY,
name varchar(255) NOT NULL,
coordinate varchar(255) NOT NULL,
location_id integer NOT NULL REFERENCES country (id)
);
CREATE TABLE source (
id SERIAL PRIMARY KEY,
name varchar(60) NOT NULL
);
CREATE TABLE item (
id SERIAL PRIMARY KEY,
title varchar(60) NOT NULL,
description varchar(900) NOT NULL,
company_id integer NOT NULL REFERENCES company (id),
date timestamp NOT NULL,
source_id integer NOT NULL REFERENCES source (id),
link varchar(255) NOT NULL,
location_id integer NOT NULL REFERENCES location (id)
);

You must create the tables before you can reference them elsewhere. Create your tables in this order:
Source,
Company,
Country,
Location,
Item
Note that you may do the first three in any order, but Country must come before Location, and Location, Source, and Company must come before Item.
You also have two extra commas at the end of the definitions of Source and Company. You must remove those.

Create the country table before referring to it location table.
Remove the dangling , in the definitions of company and source.

First you need to create table country then location followed by company,source and at the last item.

Related

MySQL/POSTGRES how to force foreign key to be NULL

I have the following SQLite3 database
CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
email VARCHAR(75) NOT NULL,
password VARCHAR(128) NOT NULL
);
CREATE TABLE IF NOT EXISTS pads (
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
name VARCHAR(100) NOT NULL,
user_id INTEGER NOT NULL REFERENCES users(id)
);
CREATE TABLE notes (
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
pad_id INTEGER REFERENCES pads(id),
user_id INTEGER NOT NULL REFERENCES users(id),
name VARCHAR(100) NOT NULL,
text text NOT NULL,
created_at DATETIME NOT NULL,
updated_at DATETIME NOT NULL
);
~
I have tried to migrate this sql schema to mysql and postgres, everything seems to be working fine except for one detail.
The table notes should accept pad_id as NULL, if there is no pad a note should be saved but when I try to save a note without a pad I get an error
sqlalchemy.exc.IntegrityError
IntegrityError: (psycopg2.errors.ForeignKeyViolation) insert or update
on table "note" violates foreign key constraint "note_pad_id_fkey"
DETAIL: Key (pad_id)=(0) is not present in table "pad".
But I should be able to save it as NULL, it works fine on SQLite3.
What should I change to be able to accomplish this?
Thank you.
Neither MySQL nor Postgres has a problem, with NULL as padod see examples
Therefore the error messahe comes from postgres, but it is because of the migration
CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY AUTO_INCREMENT NOT NULL,
email VARCHAR(75) NOT NULL,
password VARCHAR(128) NOT NULL
);
CREATE TABLE IF NOT EXISTS pads (
id INTEGER PRIMARY KEY AUTO_INCREMENT NOT NULL,
name VARCHAR(100) NOT NULL,
user_id INTEGER NOT NULL REFERENCES users(id)
);
CREATE TABLE notes (
id INTEGER PRIMARY KEY AUTO_INCREMENT NOT NULL,
pad_id INTEGER REFERENCES pads(id),
user_id INTEGER NOT NULL REFERENCES users(id),
name VARCHAR(100) NOT NULL,
`text` text NOT NULL,
created_at DATETIME NOT NULL,
updated_at DATETIME NOT NULL
);
INSERT INTO users VALUES(NULL,'test','pass')
✓
INSERT INTO notes VALUES (NULL,NULL,1,'test','text',NOW(),NOW())
✓
db<>fiddle here
CREATE TABLE IF NOT EXISTS users (
id SERIAL PRIMARY KEY NOT NULL,
email VARCHAR(75) NOT NULL,
password VARCHAR(128) NOT NULL
);
CREATE TABLE IF NOT EXISTS pads (
id SERIAL PRIMARY KEY NOT NULL,
name VARCHAR(100) NOT NULL,
user_id INTEGER NOT NULL REFERENCES users(id)
);
CREATE TABLE notes (
id SERIAL PRIMARY KEY NOT NULL,
pad_id INTEGER REFERENCES pads(id),
user_id INTEGER NOT NULL REFERENCES users(id),
name VARCHAR(100) NOT NULL,
"text" text NOT NULL,
created_at timestamp NOT NULL,
updated_at timestamp NOT NULL
);
INSERT INTO users VALUES(DEFAULT,'test','pass')
1 rows affected
INSERT INTO notes VALUES (DEFAULT,NULL,1,'test','text',NOW(),NOW())
1 rows affected
db<>fiddle here

Beginner - How to place info in tables - CREATE TABLE

I have to make a database and i'm already stuck with something. I want to make a database where i will have 5 tables. User, complaint, missing, wanted and stolen objects.
So I want to make a database where a user puts his info, then file a complaint. The user has the choice about 3 complaint subjects: missing, wanted or stolen object. So after the complaint, it should be placed in the right table.
I'm not sure on how to place the right info in the right table, I'm new with mySQL..
Here is my database for the moment:
CREATE TABLE User (
user_id INT NOT NULL AUTO_INCREMENT,
name VARCHAR(15) NOT NULL,
sexe VARCHAR(1) NOT NULL,
age INT(3) NOT NULL,
birthplace VARCHAR(50),
phoneNumber VARCHAR(20) NOT NULL,
email VARCHAR(50),
PRIMARY KEY (user_id)
);
CREATE TABLE complaint (
complaint_id INT NOT NULL AUTO_INCREMENT,
user INT NOT NULL,
complaint_sort VARCHAR(16),
title VARCHAR(150),
name VARCHAR(15),
date_complaint,
place VARCHAR(50) NOT NULL,
description VARCHAR(2000) NOT NULL,
PRIMARY KEY (complaint_id),
FOREIGN KEY (user_id)
REFERENCES Gebruiker (gebruiker_id)
);
CREATE TABLE missing (
missing_id INT NOT NULL AUTO_INCREMENT,
complaint_id INT,
PRIMARY KEY (missing_id),
FOREIGN KEY (complaint_id)
REFERENCES Complaint (complaint_id)
);
CREATE TABLE wanted (
wanted_id INT NOT NULL AUTO_INCREMENT,
complaint_id INT,
PRIMARY KEY (wanted_id),
FOREIGN KEY (complaint_id)
REFERENCES Complaint (complaint_id)
);
CREATE TABLE Stolen_objects (
Stolen_objects_id INT NOT NULL AUTO_INCREMENT,
complaint_id INT,
PRIMARY KEY (stolen_objects_id),
FOREIGN KEY (complaint_id)
REFERENCES Complaint (complaint_id)
);
There is no need to create three tables for complaint types - missing, wanted, stolen_objects.
Instead of creating three tables just add a flag in complaint table for complaintType with ENUM as data type with values like missing, wanted, stolenObjects.
Try this:
CREATE TABLE USER (
user_id INT NOT NULL AUTO_INCREMENT,
NAME VARCHAR(15) NOT NULL,
sexe VARCHAR(1) NOT NULL,
age INT(3) NOT NULL,
birthplace VARCHAR(50),
phoneNumber VARCHAR(20) NOT NULL,
email VARCHAR(50),
PRIMARY KEY (user_id)
);
CREATE TABLE complaint (
complaint_id INT NOT NULL AUTO_INCREMENT,
USER INT NOT NULL,
complaintType ENUM('Missing','Wanted','stolenObjects') NOT NULL,
complaint_sort VARCHAR(16),
title VARCHAR(150),
NAME VARCHAR(15),
date_complaint DATETIME,
place VARCHAR(50) NOT NULL,
description VARCHAR(2000) NOT NULL,
PRIMARY KEY (complaint_id),
FOREIGN KEY (user_id) REFERENCES USER (user_id)
);

SQL error 1215(HY000) cannot add foreign key constraint.

I looked through other questions on this topic, and the general consensus was to check my data type consistency. I am trying to create the table 'reviews' that has SSN and ProjectID as foreign keys, referencing SSN from Table Reviewer and ProjectID from Table Project
CREATE TABLE Reviews(
ProjectID VARCHAR(10) NOT NULL,
SSN INTEGER NOT NULL CHECK
(SSN>100000000 AND SSN<999999999),
ReviewerRole VARCHAR(50) NOT NULL,
FOREIGN KEY(SSN)REFERENCES Reviewer(SSN),
FOREIGN KEY(ProjectID)REFERENCES Project(ProjectID),
PRIMARY KEY(SSN,ProjectID)
);
The following are the create table statements for 'Project' and 'Reviewer'
CREATE TABLE Reviewer(
SSN INTEGER NOT NULL CHECK (SSN>100000000 AND SSN<999999999),
Firstname VARCHAR(50) NOT NULL,
Lastname VARCHAR(50) NOT NULL
);
CREATE TABLE Project(
ProjectID VARCHAR(10) NOT NULL,
Title VARCHAR(50),
Archived DATE NOT NULL,
ProjectStatus VARCHAR(50) NOT NULL,
PRIMARY KEY(ProjectID)
);
Project and Reviewer created without issue. My create Reviews query works if I remove the FK declaration for SSN and leave the FK declaration for ProjectID, but not the other way around.
What is the reason for the error? Is there another constraint I need to add?
You forgot to add a primary key to the SSN column in the Reviewer table. The query below builds correctly in sqlfiddle:
CREATE TABLE Reviewer(
SSN INTEGER NOT NULL CHECK (SSN>100000000 AND SSN<999999999),
Firstname VARCHAR(50) NOT NULL,
Lastname VARCHAR(50) NOT NULL,
PRIMARY KEY(SSN)
);
CREATE TABLE Project(
ProjectID VARCHAR(10) NOT NULL,
Title VARCHAR(50),
Archived DATE NOT NULL,
ProjectStatus VARCHAR(50) NOT NULL,
PRIMARY KEY(ProjectID)
);
CREATE TABLE Reviews(
ProjectID VARCHAR(10) NOT NULL,
SSN INTEGER NOT NULL CHECK
(SSN>100000000 AND SSN<999999999),
ReviewerRole VARCHAR(50) NOT NULL,
FOREIGN KEY(SSN)REFERENCES Reviewer(SSN),
FOREIGN KEY(ProjectID)REFERENCES Project(ProjectID),
PRIMARY KEY(SSN,ProjectID)
);
A foreign key can only reference to a Primary Key column in another table, you need to make SNN a primary key column.
CREATE TABLE Reviewer(
SSN INTEGER NOT NULL primary key CHECK (SSN>100000000 AND SSN<999999999),
Firstname VARCHAR(50) NOT NULL,
Lastname VARCHAR(50) NOT NULL
);
The referenced column for a foreign key column, needs to be Primary key OR have a unique constraint so your Reviewer table need to be:
CREATE TABLE Reviewer(
SSN INTEGER PRIMARY KEY CHECK (SSN>100000000 AND SSN<999999999),
Firstname VARCHAR(50) NOT NULL,
Lastname VARCHAR(50) NOT NULL
);
or
CREATE TABLE Reviewer(
SSN INTEGER NOT NULL CHECK (SSN>100000000 AND SSN<999999999),
Firstname VARCHAR(50) NOT NULL,
Lastname VARCHAR(50) NOT NULL,
UNIQUE(SSN)
);
Also as far as I know, MySQL Ignores Check Constraints, so you can remove them.

How to create table in mysql database with foreign key which is primary key of another table?

CREATE TABLE employee_detail(
e_id int auto_increment,
name varchar(20) not null,
address varchar(20) not null,
status varchar(200) not null,
primary key (e_id),
);
This is my first table(employee_login)and I want e_id as a foreign key in my next table (login) below
CREATE TABLE login(
login_id int auto_increment,
username varchar(20) not null,
password varchar(20) not null,
primary key (login_id),
e_id references employee_detail(e_id)
);
You can do it like follows :
CREATE TABLE person (
id SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT,
name CHAR(60) NOT NULL,
PRIMARY KEY (id)
);
CREATE TABLE shirt (
id SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT,
style ENUM('t-shirt', 'polo', 'dress') NOT NULL,
color ENUM('red', 'blue', 'orange', 'white', 'black') NOT NULL,
owner SMALLINT UNSIGNED NOT NULL REFERENCES person(id),
PRIMARY KEY (id)
);
I hope you understand the create table code. owner in the shirt table is the foreign key referencing id from the person table
You have several mistakes. You were missing e_id column in your Login Table, you can't add a foreign key without adding employee_detail's primary key column which in this case is e_id. Also you can't use password as a column name since it is a preestablished query you'll need to use something else like "pass".
CREATE TABLE employee_detail(
e_id int auto_increment,
name varchar(20) not null,
address varchar(20) not null,
status varchar(200) not null,
primary key (e_id));
CREATE TABLE login(
login_id INT PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(20) NOT NULL,
pass VARCHAR(20) NOT NULL,
e_id INT,
FOREIGN KEY (e_id) REFERENCES employee_detail(e_id)
);

MySQL-error 150 solution

I have the following MySQL scripts:
CREATE TABLE user_roles (
id INT AUTO_INCREMENT,
PRIMARY KEY(id),
name TEXT NOT NULL,
access INT NOT NULL DEFAULT '0'
)
CREATE TABLE users (
id INT NOT NULL AUTO_INCREMENT,
PRIMARY KEY (id),
name TEXT NOT NULL,
email TEXT NOT NULL,
password TEXT NOT NULL,
date_created DATETIME,
roles VARCHAR(50) NOT NULL,
active INT DEFAULT '1',
FOREIGN KEY(roles) REFERENCES user_roles(id)
)
It keeps giving me error 150. Maybe the database isn't well planned? Any help will be greatly appreciated.
The data types of your users.roles and user_roles.id columns must be the same for the FOREIGN KEY constraint to work correctly. Instead try making users.roles an INT:
CREATE TABLE users (
id INT NOT NULL AUTO_INCREMENT,
PRIMARY KEY (id),
name TEXT NOT NULL,
email TEXT NOT NULL,
password TEXT NOT NULL,
date_created DATETIME,
-- Change this...
roles INT NOT NULL,
active INT DEFAULT '1',
FOREIGN KEY(roles) REFERENCES user_roles(id)
)
UPDATE According to comments, users.roles should be text like "admin, moderator, etc." For correct data normalization, user_roles.id should be keyed against and to get the text name of the role, JOIN them in queries.
You need to separate your statements with a semicolon and use INTS instead of strings:
CREATE TABLE user_roles (
id INT AUTO_INCREMENT,
PRIMARY KEY(id),
name TEXT NOT NULL,
access INT NOT NULL DEFAULT 0
);
CREATE TABLE users (
id INT NOT NULL AUTO_INCREMENT,
PRIMARY KEY (id),
name TEXT NOT NULL,
email TEXT NOT NULL,
password TEXT NOT NULL,
date_created DATETIME,
roles VARCHAR(50) NOT NULL,
active INT DEFAULT 1,
FOREIGN KEY(roles) REFERENCES user_roles(id)
);