I have a project which we have to make a database for a car dealership. We have to make a Salersperson be able to view the inventory, add sales people, add cars/ car details. A customer must be able to view inventory, add cars they would think about purchasing, and then purchase the car or have a salesperson purchase the car. Salesperson must have their sales saved . I feel like my design looks a bit clunky and could be broken down better in a few more tables, but I am just drawing a blank when thinking about how else to break this up. Any suggestions?
Database Design Schema
database-design
Related Solutions
I really have to encourage you to look at the way DB schemas are handled by existing CRM systems and consider whether (1) you wouldn't be further off customizing one of these systems and (2) you're not biting off more than you can chew.
Most CRM systems I've seen have extensive customization capabilities built into them. Typically, this includes the ability to extend and/or modify the definitions of the built-in entities and the ability to add new entity types and relationships. Many of these CRM systems also have the ability to set up some pretty funky security setups, and some might be able to do something similar to what you're suggesting.
I'd also encourage you to try to pry a business scenario out of this client, as well. What's got him convinced that sales reps are going to share information? If they're working together on a team, then existing CRM systems have this covered already. If not, then I'd be a little suspicious about the premise of information sharing. Understand that sales reps are going to follow the money with respect to their behavior. If they're paid to share information, then it'll happen; otherwise, you're going to have to beat them with a stick to share anything.
Perhaps something like this:
CREATE TABLE make (
make_id INT NOT NULL,
make_name VARCHAR(25),
PRIMARY KEY(make_id);
);
CREATE TABLE model (
model_id NOT NULL,
make_id NOT NULL,
model_name VARCHAR(25),
PRIMARY KEY(model_id)
);
CREATE TABLE model_year (
model_id INT NOT NULL,
year_num INT NOT NULL,
PRIMARY KEY (model_id, year_num)
);
CREATE TABLE transmission (
transmission_id INT NOT NULL,
transmission_descrip VARCHAR(15),
PRIMARY KEY (transmission_id)
);
CREATE TABLE drive (
drive_id INT NOT NULL,
drive_descrip VARCHAR(10),
PRIMARY KEY (drive_id)
);
INSERT INTO transmission (transmission_id, transmission_descrip)
VALUES (1, 'Auto'), (2, '4-speed manual'), (3, '5-speed manual');
INSERT INTO drive (drive_id, drive_descrip)
VALUES (1, '2WD Front'), (2, '2WD Rear'), (3, '4WD'), (4, 'AWD');
To allow someone to add a 2005 Toyota Camry, first you need to make sure Toyota is in the make
table, Camry is in the model
table, and 2005 is available for the Camry:
INSERT INTO make (make_id, make_name)
VALUES (1, 'Toyota');
INSERT INTO model (model_id, model_name)
VALUES (1, 1, 'Camry');
INSERT INTO model_year (model_id, year_num)
VALUES (1, 2005);
We keep certain data on car buyers at my job, and in selecting the car type (either currently owned or looking to buy), we have them select the year, then make, then model and options from drop-downs. Each drop-down is populated on the fly based on previous answers. First the year:
SELECT DISTINCT year_num FROM model_year;
Then the make (you can't pick Pontiac for 2013):
SELECT DISTINCT m.make_id
FROM make m
INNER JOIN model mo ON mo.make_id = m.make_id
INNER JOIN model_year my ON my.model_id = mo.model_id
WHERE my.year_num = @some_year_variable;
Then the model drop-down gets populated based on:
SELECT DISTINCT model_id
FROM make m
INNER JOIN model mo ON mo.make_id = m.make_id
INNER JOIN model_year my ON my.model_id = mo.model_id
WHERE my.year_num = @some_year_variable
AND ma.make_id = @some_make_variable;
You get the idea. As far as constraining other options for a model, there are a few options, based on how strict you want to be, how much time you want to spend managing it, and how much you know about the auto industry.
Since all cars have a drive type and transmission, you might want to make those separate tables, like:
CREATE TABLE model_transmission (
model_id INT NOT NULL,
year_num INT NOT NULL, -- include this to restrict tranny based on some years
-- certain models had different trannies offered
transmission_id INT NOT NULL,
PRIMARY KEY (model_id, transmission_id) -- include year_num in PK if it is in the
-- table
);
CREATE TABLE model_drive (
model_id INT NOT NULL,
year_num INT NOT NULL, -- again, if you are up to this level of control
drive_id INT NOT NULL,
PRIMARY KEY (model_id, drive_id) --include year_num in PK if it is in the table
);
Or you could use an option table and a model_option table, like this:
CREATE TABLE option (
option_id INT NOT NULL,
option_descrip VARCHAR(25),
PRIMARY KEY (option_id)
);
INSERT INTO option (option_id, option_descrip)
VALUES (1, 'Transmission'), (2, 'Drive'), (3, 'Doors');
CREATE TABLE model_option (
model_id INT NOT NULL,
option_id INT NOT NULL,
option_value VARCHAR(15),
PRIMARY KEY (model_id, option_id) -- include year_num as above if desired
);
INSERT INTO model_option (model_id, option_id, option_value)
VALUES (1, 1, '1'), (1, 2, '1'), (1, 3, '4'); -- All Camrys now have automatic,
-- front-wheel drive, and 4-door options
-- available
I prefer the first approach as you can see the problem with referential integrity inherent in the second, plus it makes it more awkward to restrict available options. The table for listed cars might be like this:
CREATE TABLE car (
listing_id INT NOT NULL,
year_num INT NOT NULL,
model_id INT NOT NULL,
transmission_id INT NOT NULL,
drive_id INT NOT NULL,
doors INT NOT NULL, -- might want varchar to include 'hatchback' or other options
mileage INT,
customer_id INT NOT NULL,
PRIMARY KEY (listing_id)
);
If this doesn't address a particular feature you believe you need just add a comment.
Best Answer
I don't really understand what you mean by "looks a bit clunky and could be broken down better in a few more tables"; something looking "clunky", however that applies to database design, doesn't seem like a good reason to breaking things up. Unlike fighting the dark force, you probably should use logic, not your feelings.
For a suggestion, may be you could answer (to yourself) to some questions about your model, such as:
Why do you think that "car make/model" is a separate entity and not simply attributes of a "car" entity?
Why
car.car_lot varchar(255)
referencescar_lot.lot_id (integer)
?Why
for_sale_cars
? What entity does that represent?Is
customer.customer_cars varchar(255)
intended to store a list of cars? That would violate 1NF. And how is that then different fromsaved_cars
?Why do you think you need an extra key in
saved_cars
?Which of the requirements you have listed cannot be addressed by your model? Are there any requirements that are missing?