How to create tables with columns that have range in MySQL? - mysql

I want to create a table for the following:
One pokemon must have and can only have one trainer.
One pokemon may evolve into many other pokemons.
The pokemon name has a maximum of 50 characters and can not be
blank.
The dex number has 3-numeric-digit and can not be blank.
The pokemon height is a whole number and ranges [0, 1,000] cm
inclusive.
The pokemon weight ranges [0.00, 1,000.00] kg inclusive.
The pokemon color has a maximum of 20 characters.
The pokemon type has a maximum of 15 characters. If an INSERT
doesn't list the pokemon type value, it should default to Grass
I am stuck specifically on number 5. How do I apply that to my table? Also, another question is how do I apply numbers 5-6 and 8 also? How can I also assign the EvolvedFrom as one of the Foreign Keys? I don't know where to refrence it. I am a little bit confused, so please help. Thank you so much.
Table Reference
ERD of the table to be created
This is my sample code that I have created:
CREATE TABLE pokemon(
pokemonId int,
pokemonDexNum int(3) NOT NULL,
pokemonName varchar(50) NOT NULL,
pokemonHeightCm int unsigned,
CONSTRAINT CHK_pokemonHeightCm CHECK (pokemonHeightCm <= 1000)
pokemonWeightKg int NOT NULL,
pokemonColor varchar(50),
pokemonType varchar(50),
trainerId int NOT NULL,
evolvedFrom varchar(50),
PRIMARY KEY (pokemonId),
FOREIGN KEY (trainerId) REFERENCES trainer(trainerId),
FOREIGN KEY (evolvedFrom) REFERENCES pokemon(evolvedInto) --THIS LINE IS INCORRECT. HELP--
);

Try to include a constrain as below.
CREATE TABLE pokemon(
pokemonHeightCm int() NOT NULL,
CONSTRAINT pokemonHeightCm_Ck CHECK (pokemonHeightCm BETWEEN 0 AND 1000),
... and the rest

Try the below, I haven't tested the syntaxes:
CREATE TABLE pokemon(
pokemonId int ,
pokemonDexNum int(3) NOT NULL, #rule 4
pokemonName varchar(50) NOT NULL, #rule 3
pokemonHeightCm int NOT NULL, CONSTRAINT CHK_pokemonHeightCm CHECK (pokemonHeightCm <= 1000), #rule 5
pokemonWeightKg decimal NOT NULL, CONSTRAINT CHK_pokemonWeightKg CHECK (pokemonWeightKg <= 1000.00), #rule 6
pokemonColor varchar(20), #rule 7
pokemonType varchar(15) NOT NULL DEFAULT 'Grass', #rule 8
trainerId int NOT NULL,
evolvedFrom int,
PRIMARY KEY (pokemonId), #rule 1
FOREIGN KEY (trainerId) REFERENCES trainer(trainerId), #rule 1
FOREIGN KEY (evolvedFrom) REFERENCES pokemon(pokemonId) #rule 2
);

Related

How can I limit INT in MySQL? [duplicate]

This question already has an answer here:
SQL Integer Range When Creating Tables
(1 answer)
Closed 1 year ago.
I'm creating a college grading system with Java. I have a credit number column in courses table. I want this credit number to be limited between 1 to 8. I don't want any other number to be entered. I'm a beginner.
CREATE TABLE courses(
id INT PRIMARY KEY,
course_name VARCHAR(50) NOT NULL,
credit_number BETWEEN 1 AND 8 NOT NULL,
course_description VARCHAR(255));
Use a check constraint:
CREATE TABLE courses (
id INT PRIMARY KEY,
course_name VARCHAR(50) NOT NULL,
credit_number int NOT NULL,
course_description VARCHAR(255),
CONSTRAINT chk_courses_credit_number CHECK (credit_number BETWEEN 1 AND 8)
);
Slight variation on the accepted answer -
You could also use TINYINT instead of INT, which would restrict the possible range to -128 to 127 (one byte), which is okay since you only need 1-8:
https://dev.mysql.com/doc/refman/5.7/en/integer-types.html
CREATE TABLE courses (
id INT PRIMARY KEY,
course_name VARCHAR(50) NOT NULL,
credit_number TINYINT NOT NULL,
course_description VARCHAR(255),
CONSTRAINT chk_courses_credit_number CHECK (credit_number BETWEEN 1 AND 8)
);

MySQL - add data into 2 tables and 1 has foreign key

I'm a totally MySQL newcomer. Sr if my question is quite obvious. I got 2 tables
CREATE TABLE tbl_addresses(
PK_ADDRESS_ID int NOT NULL AUTO_INCREMENT,
house_number int NOT NULL,
street varchar(35),
district varchar(35),
city varchar(35),
postcode varchar(8),
PRIMARY KEY (PK_ADDRESS_ID)
);
CREATE TABLE tbl_people(
PK_PERSON_ID int NOT NULL AUTO_INCREMENT,
title varchar(6) NOT NULL, # Master / Mister therefor 6 is max
forename varchar(35) NOT NULL,
surname varchar(35) NOT NULL,
date_of_birth DATE NOT NULL,
contact_number varchar(12) NOT NULL,
FK_ADDRESS_ID int NOT NULL,
PRIMARY KEY (PK_PERSON_ID),
FOREIGN KEY (FK_ADDRESS_ID) REFERENCES tbl_addresses (PK_ADDRESS_ID)
);
and I'm trying to import data into these tables from Java using below syntaxes
INSERT INTO tbl_addresses (house_number,street,district,city,postcode) VALUES ('1','abc','','abc','abc');
INSERT INTO tbl_people (title,forename,surname,date_of_birth,contact_number) VALUES ('Mr','Tri ','Nguyen','1991-1-1','0123456789');
I got an error Field 'FK_ADDRESS_ID'doesn't have a default value and data actually goes into tbl_addresses but not tbl_people. Am I missing anything? Thanks in advance!
This error is being caused by that you labelled the FK_ADDRESS_ID field in the tbl_people table as NOT NULL, yet you are trying to do an INSERT without specifying a value for this column.
So something like this would work without error:
INSERT INTO tbl_people (title, forename, surname, date_of_birth,
contact_number, FK_ADDRESS_ID)
VALUES ('Mr', 'Tri', 'Nguyen', '1991-1-1', '0123456789', 1);
You could also specify a default value for FK_ADDRESS_ID (the error message you got alluded to this). Here is how you could adda default value:
ALTER TABLE tbl_people MODIFY COLUMN FK_ADDRESS_ID int NOT NULL DEFAULT 1
But because FK_ADDRESS_ID is a key into another table, the value should really be based on the primary key in tbl_addresses.
The fact that you are using a foreign key isn't the reason that you are getting this error. Let's take a look at your column definition.
FK_ADDRESS_ID int NOT NULL,
This is not null but does not a default. Now a look at your insert statement
INSERT INTO tbl_people (title,forename,surname,date_of_birth,contact_number)
FK_ADDRESS_ID isn't in your column list but it cannot be null and doesn't have a default so what can mysql do? Produce an error of course.
The best bet is to define that column as nullable.
Let's revisit the foreign key constraint.
FOREIGN KEY (FK_ADDRESS_ID) REFERENCES tbl_addresses (PK_ADDRESS_ID)
What this really says is that if you asign a value to FK_ADDRESS_ID that value should be present in PK_ADDRESS_ID column in tbl_address
as a side note, it's customary to use lower case for table/column names.

How should I create a table based in the following requirements? [SQL]

I have got the following JSON file:
"vehicle_number" : 91,
"pit_stops" : [ {
"pit_in_elapsed_time" : 1874.0926,
"pit_out_elapsed_time" : 0.0
}, {
"pit_in_elapsed_time" : 1992.9723,
"pit_out_elapsed_time" : 0.0
}, {
"pit_in_elapsed_time" : 2862.2129,
"pit_out_elapsed_time" : 0.0
} ],
My table has to keep the following value:
vehicle
pit_int_elapsed_time
pit_out_elapse_time
How do I create a table based on this??
create table pitstop (
vehicle varchar(50) not null,
inTime varchar(50) not null,
outTime varchar(50) not null,
constraint pk_id primary key(inTime, outTime))
I am not sure if this would be the ideal way of create the table?
Regards
EDIT
I have been thinking of creating 2 main tables. One for the vehicles (vehicleID as pk, pitstopFK as foreign key).
create table vehicles (
vehicle varchar(50) primary key not null
pitstops_fk int not null );
Also the pitstops table:
create table pitstops (
id int primary key autoincrement not null,
inTime varchar(50) not null,
outTime varchar(50) not null,
constraint u_time UNIQUE (inTime, outTime))
vehicles ----- pitstops ( 1 to many)
It's hard to say much without a better understanding of the problem you're trying to solve, but I would say:
if vehicle ID is always an integer, an unsigned int will generally perform better than treating it as text
using a SQL date type for the inTime and outTime columns will allow you to use SQL time/date operations. If the timestamps represent real-world times consider DATETIME or TIMESTAMP, if they are elapsed seconds since the start of a race or something like that, a floating point numeric type would probably be a better choice.
the combination of inTime and outTime doesn't make sense as a primary key, since as you note in the comment it is not necessarily unique. In thinking about designating a primary key, don't (just) think about uniqueness, but about how you'd want to refer to a pitstop event from other tables. In the case I would probably suggest a synthetic auto-incremented unsigned int as a primary key.
First of all, if it is a time you want to store in your database i wouldn't use varchar. Instead try to use Float or Real.
The next thing is, that you should take your vehicle in your primary key as well.
I also would recommend to introduce a ID to your Database.
Something like this:
CREATE TABLE pitstop (
ID int NOT NULL AUTO_INCREMENT,
vehicle varchar(50) NOT NULL,
inTime float NOT NULL,
outTime float NOT NULL,
constraint pk_id primary key(ID, vehicle))

What does this error mean? SQL Error: ORA-02270: no matching unique or primary key for this column-list

I keep getting the error code 'ORA-02270' and no matter what I try, I can't seem to fix it. Below are my Create Table statements:
CREATE TABLE student
(
studentID CHAR(8) PRIMARY KEY,
studentName VARCHAR(25) NOT NULL,
studentAddress VARCHAR(30) NOT NULL,
studentDOB DATE NOT NULL,
studentGender CHAR(1) NOT NULL CHECK ((studentGender = 'F') OR (studentGender = 'M')),
studentNationality VARCHAR(15) NOT NULL,
studentCourse VARCHAR(30) NOT NULL,
studentSemesterExcellent CHAR(1) NOT NULL CHECK ((studentSemesterExcellent = 'Y') OR (studentSemesterExcellent = 'N'))
);
CREATE TABLE leaseAgreement
(
leaseNo CHAR(6) PRIMARY KEY,
studentID CHAR(8) NOT NULL,
leaseAccommodationType VARCHAR2(10) NOT NULL,
leaseDuration NUMBER NOT NULL,
leaseStartDate DATE NOT NULL,
leaseEndDate DATE,
studentSemesterExcellent CHAR(1) NOT NULL CHECK ((studentSemesterExcellent = 'Y') OR (studentSemesterExcellent = 'N')),
FOREIGN KEY (studentID) REFERENCES student(studentID),
FOREIGN KEY (studentSemesterExcellent) REFERENCES student(studentSemesterExcellent)
);
Am I not allowed to have two foreign keys from the same table? Please can someone explain this error and point me in the right direction. Thank you.
First, the answer from mustaccio is correct.
The column 'studentSemesterExcellent' in table 'student' is no key column. You can not reference it in a foreign key constraint.
And if you make it unique you can only have two rows in the student table, not what you are intending.
Second, you have tagged the question both with MySQL and Oracle. Choose one!
Third, you only need one FK if it is a not null column. Don't make it harder on yourself.
Fourth, if this is Oracle database, the advice is to only use varchar2() for string data. The char and varchar datatypes exist for compatibility reasons.

Optimize query many field mysql

I'm confused about how to chose best index for my table:
Have this table:
Hotel
-has_1
...
-has-5
-nota_AVG
-nota_1
-nota_2
-nota_3
and this
Nota_hotel
-nota_1
-nota_2
-nota_3
-id_hotel
Field with name "nota_*" from hotel is update from a trigger on table Nota_hotel and this field changed frequently.
My need do some query like
select * from hotel where has_X = true or has_Y=true order by nota_Z
where my clause "WHERE" can have 1 has_X or many has_* fields in query depend on what checkbox is selected.
I want know what is best practice to put index, add for every field "nota_" a index and for fields "has_" create a single index(has_1,...,has_5) or add for every field "has_" a index too, and if have this much index is possible to strangle my MySQL server ?
create table hotel(
id int primary key auto_increment,
nume varchar(255),
index hotel_nume_index(nume),
nume_oras varchar(100),
nume_zona varchar(100),
nume_tara varchar(100),
foreign key (nume_oras,nume_zona,nume_tara) references oras(nume,nume_zona,nume_tara) ON DELETE CASCADE,
descriere text,
stele int,
map_x double,
map_y double,
has_sauna TINYINT(1),
has_piscina TINYINT(1),
has_parcare TINYINT(1),
has_restaurant TINYINT(1),
has_fitness TINYINT(1),
distanta_obiectiv double,
code_api1 varchar(255),
code_api2 varchar(255),
code_api3 varchar(255),
intern TINYINT(1),
nota_hotel double,
nota_restaurant double,
nota_locatie double,
nota_conditii double,
nume_comision varchar(100),
foreign key (nume_comision) references comision(nume)
);
create table nota_hotel(
fb_id varchar(100),
data DATETIME,
nota_restaurant double,
nota_locatie double,
nota_conditi double,
comentariu text,
nume_user varchar(255),
id_hotel int,
foreign key (id_hotel) references hotel(id) ON DELETE CASCADE
);
Here is full definition
this is a work in progress answer. will add to it.
let's say you have 5 has_ columns, like has_restaurant, has_pool, has_pool and searches are on true types like before, as in 'it is true that it has a pool'
for starters, convert them into one column using powers of 2. let us call that hasX and its column value is a bit-wise OR of the below (that are not columns)
has_restaurant (2^0) 1
has_pool (2^1) 2
has_wifi (2^2) 4
has_piscina (2^3) 8
has_sauna (2^4) 16
so if the hotel has wifi and sauna then the hasX column will contain (at least) the bits turned on with value 20, but could contain a value of 21 (has a restaurant too). but the search was on 'i want wifi and sauna' so it finds the 21 too. it is a mask
so at this point we have added one index to hotel, on column hasX
Edit
I just bombed on this notion as i assumed i could craft a bit-wise search and that seems quite impossible after reading about it. The following seems to be the best work-up
CREATE TABLE hotel (
hotel_id int primary key auto_increment PRIMARY KEY,
/* some more fields... */
);
CREATE TABLE hotel_flags (
flag_id TINYINT UNSIGNED NOT NULL
, description VARCHAR(100) NOT NULL
, PRIMARY KEY (flag_id)
);
**the following is the intersect table**
CREATE TABLE hotel_flags_intersect (
hotel_id int not null
, flag_id TINYINT UNSIGNED NOT NULL
, PRIMARY KEY (hotel_id, flag_id)
, UNIQUE INDEX reverse_pk (flag_id, hotel_id)
);
humbly borrowed from http://forums.mysql.com/read.php?24,35318,35640#msg-35640