Related
I need to create the following database:
For semi-trucks I don't need extra subtypes, while for Car I need to have only those 3 subtypes and also for Sedan I need the four subtypes.
For SELECTs I will use JOINs (normalized database) but I need to find an easy way to make INSERTs.
Vehicle table stores common information
Semi-truck stores specific information for semis
Car tables has specific fields for cars and a car_type field which is linked to the three subtypes
Van, Suv and Sedan (and other types if I would need them) should be in one table CAR_TYPE
However, for Sedan type I need to have additional subtypes which maybe should be contained in another table. These subtypes are not needed for Suvs and Vans (in real life suv, vans can have the same subtypes as sedans but not in my case).
I need this database to be created exactly as it is in the diagram.
So far, my first approach is to have the following tables:
Vehicle: veh_id, veh_type(Semi, car), ..., other_fields
Vehicle_semis: veh_id, ..., other_semis_fields
Vehicle_car: veh_id, car_type(Van, Suv, Sedan), other_car_specific_fields
Car_type: car_type_id, type
Sedan_type: sedan_type_id, type
My problem is that I'm not sure this would be the right approach, and I don't know exactly how to create relationships between the tables.
Any ideas?
Thank you!
UPDATE:
The following diagram is based on #Mike 's answer:
Before I get started, I want to point out that "gas" describes either fuel or a kind of engine, not a kind of sedan. Think hard before you keep going down this path. (Semantics are more important in database design than most people think.)
What you want to do is fairly simple, but not necessarily easy. The important point in this kind of supertype/subtype design (also known as an exclusive arc) is to make it impossible to have rows about sedans referencing rows about semi-trucks, etc..
MySQL makes the code more verbose, because it doesn't enforce CHECK constraints. You're lucky; in your application, the CHECK constraints can be replaced by additional tables and foreign key constraints. Comments refer to the SQL above them.
create table vehicle_types (
veh_type_code char(1) not null,
veh_type_name varchar(10) not null,
primary key (veh_type_code),
unique (veh_type_name)
);
insert into vehicle_types values
('s', 'Semi-truck'), ('c', 'Car');
This is the kind of thing I might implement as a CHECK constraint on other platforms. You can do that when the meaning of the codes is obvious to users. I'd expect users to know or to figure out that 's' is for semis and 'c' is for cars, or that views/application code would hide the codes from users.
create table vehicles (
veh_id integer not null,
veh_type_code char(1) not null,
other_columns char(1) default 'x',
primary key (veh_id),
unique (veh_id, veh_type_code),
foreign key (veh_type_code) references vehicle_types (veh_type_code)
);
The UNIQUE constraint lets the pair of columns {veh_id, veh_type_code} be the target of a foreign key reference. That means a "car" row can't possibly reference a "semi" row, even by mistake.
insert into vehicles (veh_id, veh_type_code) values
(1, 's'), (2, 'c'), (3, 'c'), (4, 'c'), (5, 'c'),
(6, 'c'), (7, 'c');
create table car_types (
car_type char(3) not null,
primary key (car_type)
);
insert into car_types values
('Van'), ('SUV'), ('Sed');
create table veh_type_is_car (
veh_type_car char(1) not null,
primary key (veh_type_car)
);
Something else I'd implement as a CHECK constraint on other platforms. (See below.)
insert into veh_type_is_car values ('c');
Only one row ever.
create table cars (
veh_id integer not null,
veh_type_code char(1) not null default 'c',
car_type char(3) not null,
other_columns char(1) not null default 'x',
primary key (veh_id ),
unique (veh_id, veh_type_code, car_type),
foreign key (veh_id, veh_type_code) references vehicles (veh_id, veh_type_code),
foreign key (car_type) references car_types (car_type),
foreign key (veh_type_code) references veh_type_is_car (veh_type_car)
);
The default value for veh_type_code, along with the foreign key reference to veh_type_is_car, guarantees that this rows in this table can be only about cars, and can only reference vehicles that are cars. On other platforms, I'd just declare the column veh_type_code as veh_type_code char(1) not null default 'c' check (veh_type_code = 'c').
insert into cars (veh_id, veh_type_code, car_type) values
(2, 'c', 'Van'), (3, 'c', 'SUV'), (4, 'c', 'Sed'),
(5, 'c', 'Sed'), (6, 'c', 'Sed'), (7, 'c', 'Sed');
create table sedan_types (
sedan_type_code char(1) not null,
primary key (sedan_type_code)
);
insert into sedan_types values
('g'), ('d'), ('h'), ('e');
create table sedans (
veh_id integer not null,
veh_type_code char(1) not null,
car_type char(3) not null,
sedan_type char(1) not null,
other_columns char(1) not null default 'x',
primary key (veh_id),
foreign key (sedan_type) references sedan_types (sedan_type_code),
foreign key (veh_id, veh_type_code, car_type) references cars (veh_id, veh_type_code, car_type)
);
insert into sedans (veh_id, veh_type_code, car_type, sedan_type) values
(4, 'c', 'Sed', 'g'), (5, 'c', 'Sed', 'd'), (6, 'c', 'Sed', 'h'),
(7, 'c', 'Sed', 'e');
If you have to build additional tables that reference sedans, such as gas_sedans, diesel_sedans, etc., then you need to build one-row tables similar to "veh_type_is_car" and set foreign key references to them.
In production, I'd revoke permissions on the base tables, and either use
updatable views to do the inserts and updates, or
stored procedures to do the inserts and updates.
I refer you to the "Info" tab under the following three tags:
class-table-inheritance
single-table-inheritance
shared-primary-key
The first two describe the two major design patterns for dealing with a class/subclass (aka type/subtype) situation when designing a relational database. The third descibes a technique for using a single primary key that gets assigned in the superclass table and gets propagated to the subclass tables.
They don't completely answer the questions you raise, but they shed some light on the whole topic. This topic, of mimicking inheritance in SQL, comes up over and over again in both SO and the DBA area.
CREATE TABLE invoices(
invoice_id INT PRIMARY KEY,
category_id INT NOT NULL,
supplier_id INT NOT NULL,
invoice_due_date VARCHAR(12),
invoice_supplier VARCHAR(255) NOT NULL,
invoice_contact VARCHAR(255) NOT NULL,
invoice_amount INT,
invoice_paid BOOL DEFAULT FALSE,
CONSTRAINT invoice_fk_supplier
FOREIGN KEY(supplier_id)
REFERENCES suppliers(supplier_id),
CONSTRAINT invoice_fk_category
FOREIGN KEY(category_id)
REFERENCES categories(category_id)
);
INSERT INTO invoices(invoice_id, category_id, supplier_id,
invoice_supplier, invoice_due_date, invoice_contact, invoice_amount,
invoice_paid) VALUES
(1, 2, 1, "Pepsi" '12-24-2017', 'James Hatfield', 23500, FALSE),
(2, 2, 2, "Ragu", '12-20-2017', 'Mike Richards', 8650, FALSE),
(3, 2, 3, "Miguel's Produce", '12-18-2017', 'Miguel Profesa', 6750,
FALSE),
(4, 2, 4, "Butch's Butcher Shop", '12-15-2017', 'Rick Santana', 9550,
FALSE),
(5, 2, 5, "Cafe Carmen", '12-04-2017', 'Carmen San Diego', 1250, FALSE);
I am using MySQL WorkBench 6.3, and I keep getting this error
"Error Code: 1136. Column count doesn't match value count at row 1"
whenever I am trying to run my INSERT statement to add data to the database. I have no issues with my other tables, only this one. However, when I was looking up this error, it seems that many times the error comes down to not having a matching number of values to the records, but I have triple checked that I have 8 fields and 8 values.
If anyone could help me out or explain it at all, it would be much appreciated as this has had me stumped for a few hours.
Cheers!
First and foremost "Pepsi" '12-24-2017' has no comma in between ..typo error
(1, 2, 1, "Pepsi" '12-24-2017', 'James Hatfield', 23500, FALSE),
SEcondly your fourth column is VARCHAR(12) & not VARCHAR(255)
Primary key insertion has a lot of conflict...to be on safe side...keep PK auto
CREATE TABLE invoices(
invoice_id INT NOT NULL AUTO_INCREMENT,
category_id INT NOT NULL,
supplier_id INT NOT NULL,
invoice_due_date VARCHAR(255),
invoice_supplier VARCHAR(255) NOT NULL,
invoice_contact VARCHAR(255) NOT NULL,
invoice_amount INT,
invoice_paid BOOL DEFAULT FALSE,
CONSTRAINT invoice_fk_supplier
FOREIGN KEY(supplier_id)
REFERENCES suppliers(supplier_id),
CONSTRAINT invoice_fk_category
FOREIGN KEY(category_id)
REFERENCES categories(category_id)
);
and then do an insert like..
INSERT INTO invoices( category_id, supplier_id,
invoice_supplier, invoice_due_date, invoice_contact, invoice_amount,
invoice_paid) VALUES
( 2, 1, "Pepsi", "12-24-2017", "James Hatfield", 23500, FALSE)
I was preparing to create a website using PHPMyAdmin and I bang into a problem : I don't understant why my code does things I don't want.
This is the code to create the tables and some random entries :
create table stud (
matrnr int primary key,
pname Varchar(30) not null
);
create table prof (
persnr int primary key,
pname Varchar(50) not null
);
create table vorl (
vorlnr int primary key,
titel varchar(50),
prof int references prof(persnr) on delete set null
);
create table prüfen (
stud int references stud(matrnr) on delete cascade,
vorl int references vorl(vorlnr),
prof int references prof(persnr) on delete set null,
note float,
primary key(Stud, vorl)
);
insert into stud values
(1, 'G'),
(2, 'F'),
(3, 'C');
insert into Prof values
(1, 'M'),
(2, 'L'),
(3, 'M');
insert into vorl values
(1, 'Info1', 'M'),
(1, 'Info2', 'L'),
(1, 'Info3', 'M');
insert into prüfen values
(1, 1, 1, 2.0),
(1, 2, 1, 1.7),
(2, 3, 2, 2.3);
At this position I tried
Insert into prüfen values (3, 1, 4, 2.0);
but the was still only 3 lines in the table prüfen.
Any help is wellcome.
Have a good week.
Your final insert failed because it references a professor with a prof ID of 4, which does not exist in the prof table.
If you look closely at your definition for the prüfen table, this will be more clear:
create table prüfen (
stud int references stud(matrnr) on delete cascade,
vorl int references vorl(vorlnr),
prof int references prof(persnr) on delete set null,
note float,
primary key(Stud, vorl)
);
The field prof is a foreign key into the prof table. MySQL will require that this field references a professor which actually exists. It does not in the case of your final insert. To get around this error, you could create such a professor, e.g.
insert into Prof values
(4, 'M');
You didn't report an error in your question, which seems off to me. Maybe you failed to mention it, or perhaps your error reporting is turned off for some reason.
Hey guys I've searched for answers through the forums but to no avail so I'm using MySql and I'm trying to insert statements for certain tables and they aren't going into the tables and I'm getting errors like "Msg 8152, Level 16, State 14, Line 1
String or binary data would be truncated. The statement has been terminated."
These are the statements I'm having problems with.`INSERT INTO Course VALUES
INSERT INTO Course VALUES (12345, 'DatabaseManagement', '2015-2-1', '2014-5-9');
INSERT INTO Course VALUES (12346, 'Calculus', '2015-1-12', '2015-5-9');
INSERT INTO Course VALUES (12347, 'Biology', '2015-1-3', '2015-5-9');
INSERT INTO Course VALUES (12348, 'Chemistry', '2015-1-2', '2015-5-9');
INSERT INTO Grade VALUES (10, 12345, 012, 'A');
INSERT INTO Grade VALUES (11, 12346, 013, 'B');
INSERT INTO Grade VALUES (12, 12347, 014, 'C');
INSERT INTO Grade VALUES (13, 12348, 015, 'D');
INSERT INTO Grade VALUES (14, 12345, 016, 'B');
INSERT INTO Student VALUES (54321, 'Rachel', 'Cotterel', '2013-4-15', '2016-3-4');
INSERT INTO Student VALUES (54320, 'John', 'Smith', '2012-1-23', NULL);
INSERT INTO Student VALUES (54319, 'Johny', 'Depp', '2010-5-12', '2012-10-10');
INSERT INTO Student VALUES (54318, 'Orlando', 'Bloom', '2014-6-24', NULL);
INSERT INTO Student VALUES (54317, 'Linda', 'Jacob', '2015-4-4', '2019-8-6');
I didn't get any error for insert into Course statements. I got error for INSERT INTO Grade statements. Its because there is no reference available for StudentID 012,013 etc in Student table. And you are trying to add them in grade table.
Try using this:
INSERT INTO table1 (column1,column2,column3,...)
VALUES (value1,value2,value3,...);
These are the field types:
CREATE TABLE Course
(
CourseID int,
Description varchar(20) NOT NULL,
StartDate DATE NOT NULL,
EndDate DATE NOT NULL,
CONSTRAINT [PK_CourseID] PRIMARY KEY (CourseID)
);
CREATE TABLE Grade
(
GradeID integer(10) NOT NULL,
CourseID integer(10) NOT NULL,
StudentID integer(10) NOT NULL,
Grade varchar (10) NULL,
CONSTRAINT [PK_GradeID] PRIMARY KEY (GradeID),
CONSTRAINT [FK_CourseID] FOREIGN KEY (CourseID) REFERENCES Course(CourseID),
CONSTRAINT [FK_StudentID] FOREIGN KEY (StudentID) REFERENCES Student(StudentID)
);
CREATE TABLE Student
(
StudentID integer(10) NOT NULL,
FirstName varchar(45) NOT NULL,
LastName varchar(45) NOT NULL,
RegistrationDate varchar (45) NOT NULL,
GraduationDate DATE NULL,
CONSTRAINT [PK_StudentlID] PRIMARY KEY (StudentID)
);
String or binary data would be truncated
The reason that you get this message should be that you are trying to insert some value to some field to which you haven't assigned enough size to hold the value.
Can you send what the exact error message you get?
I tried to do it myself.But the error I got was from you insertion query to Grade table foreign key fails which refer Student table because you are trying to insert Student_IDs which are not there in you Student table
I am looking to create a MySQL shop that is capable of handling multiple categories. I have all of the category facility etc sorted but the bit I am not getting anywhere with is this..
Each item can have multiple options, for example a T-Shirt should have the options 'Colour' and 'Size'. I then need to create a number of variations/ derived products from the parent product specifying that an Extra Large Blue T-Shirt has 20 in stock (for example). The problem is, it's not just clothes being sold, it could be any number of things. So I also need this schema to be able to handle an infinite number of variants such as '6mm' 'Large' Birthday Card with 'Sports Car' design. 6mm, Large, and 'Ace' being the variables. This way I am able to ensure that we do not have any stock control issues. If it is any use to you, below is my current site structure.
Existing Database Schema http://www.hallwaystudios.com/screenshots/uploads/g5B7SNKU.png
I hope you understand what I mean and that someone has an answer to my problem! Many thanks in advance (and after of-course)
Not too sure what the problem is here... I'd probably create four tables:
-- a table of item types (t-shirt, birthday card, etc.)
CREATE TABLE ItemTypes (
TypeID INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
TypeName VARCHAR(20) NOT NULL
);
-- a table of associated properties
CREATE TABLE TypeProperties (
PropertyID INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
TypeID INT NOT NULL,
PropName VARCHAR(20) NOT NULL,
INDEX(Property, TypeID),
FOREIGN KEY(TypeID) REFERENCES ItemTypes(TypeID)
);
-- a table of specific items (XL Blue t-shirt, large bday card w/sports car, etc.)
CREATE TABLE Items (
ItemID INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
TypeID INT NOT NULL,
ItemName VARCHAR(100) NOT NULL,
ItemPrice DECIMAL UNSIGNED NOT NULL,
ItemStock INT UNSIGNED NOT NULL,
INDEX(ItemID, TypeID),
FOREIGN KEY(TypeID) REFERENCES ItemTypes(TypeID)
);
-- the dictionary of property values
CREATE TABLE ItemProperties (
ItemID INT NOT NULL,
TypeID INT NOT NULL,
PropertyID INT NOT NULL,
Value VARCHAR(20) NOT NULL,
PRIMARY KEY(ItemID, Property),
INDEX(ItemID, TypeID),
INDEX(PropertyID, TypeID),
FOREIGN KEY( TypeID) REFERENCES ItemTypes ( TypeID),
FOREIGN KEY(ItemID, TypeID) REFERENCES Items (ItemID, TypeID),
FOREIGN KEY(PropertyID, TypeID) REFERENCES TypeProperties(PropertyID, TypeID)
);
It ought to be fairly obvious, but just in case, the example data would look something like:
INSERT INTO ItemTypes (TypeID, TypeName) VALUES
(1, 'T-Shirt' ),
(2, 'Birthday Card'),
(3, 'Balloon' );
INSERT INTO TypeProperties(PropertyID, TypeID, PropName) VALUES
(51, 1, 'Colour' ), (52, 1, 'Size'),
(53, 2, 'Size/mm'), (54, 2, 'Size'), (55, 2, 'Design'),
(56, 3, 'Colour' );
INSERT INTO Items (ItemID, TypeID, ItemName, ItemPrice, ItemStock) VALUES
(101, 1, 'Extra Large Blue T-Shirt', 10.99, 20),
(102, 2, '6mm Large Birthday Card with Sports Car Design', 2.99, 17),
(103, 1, 'Extra Large Black T-Shirt', 10.99, 5),
(104, 3, 'Pink balloon', 0.10, 60);
INSERT INTO ItemProperties (ItemID, TypeID, PropertyID, Value) VALUES
(101, 1, 51, 'Blue' ),
(101, 1, 52, 'Extra Large'),
(102, 2, 53, '6' ),
(102, 2, 54, 'Large' ),
(102, 2, 55, 'Sports Car' ),
(103, 1, 51, 'Black' ),
(103, 1, 52, 'Extra Large'),
(104, 3, 56, 'Pink' );