databasedatabase-designdatabase-link

How to design this database layout?


I am working on a site similar to Craigslist where users can make postings and sell items in different cities. One difference between my site and Craigslist will be you will be able to search by zip code instead of having all of the cities listed on the page.

I already have the ZIP Code database that has all of the city, state, latitude, longitude, and zip code info for each city. Okay, so to dive into what I need done and what I need help with:

  1. Although I have the ZIP Code database, it is not setup perfectly for my use. (I downloaded it from the internet for free from http://zips.sourceforge.net/)

  2. I need help setting up my database structure (e.g. how many different tables should I use and how should I link them).

I will be using PHP and MySQL.

These our my thoughts so far on how the database can be setup: (I am not sure if this will work though.)

Scenario

Someone goes to the homepage and it will tell them, "Please enter your ZIP Code.". If they enter "17241" for example, this ZIP Code is for a city named Newville located in Pennsylvania. The query would look like this with the current database setup:

SELECT city FROM zip_codes WHERE zip = 17241;

The result of the query would be "Newville". The problem I see here now is when they want to post something in the Newville section of the site, I will have to have an entire table setup just for the Newville city postings. There are over 42,000 cities which means I would have to have over 42,000 tables (one for each city) so that would be insane to have to do it that way.

One way I was thinking of doing it was to add a column to the ZIP Code database called "city_id" which would be a unique number assigned to each city. So for example, the city Newville would have a city_id of 83. So now if someone comes and post a listing in the city Newville I would only need one other table. That one other table would be setup like this:

CREATE TABLE postings (
posting_id INT NOT NULL AUTO_INCREMENT,
for_sale LONGTEXT NULL,
for_sale_date DATETIME NULL,
for_sale_city_id INT NULL,
jobs LONGTEXT NULL,
jobs_date DATETIME NULL,
jobs_city_id INT NULL,
PRIMARY KEY(posting_id)
);

(The for_sale and job_ column names are categories of the types of postings users will be able to list under. There will be many more categories than just those two but this is just for example.)

So now when when someone comes to the website and they are looking for something to buy and not sell, they can enter their ZIP Code, 17241, for example, and this is the query that will run:

SELECT city, city_id FROM zip_codes WHERE zip = 17241; //Result: Newville 83

(I will be using PHP to store the ZIP Code the user enters in SESSIONS and Cookies to remember them throughout the site)

Now it will tell them, "Please choose your category.". If they choose the category "Items For Sale" then this is the query to run and sort the results:

SELECT posting_id, for_sale, for_sale_date FROM postings WHERE for_sale_city_id = $_SESSION['zip_code'];

So now my question is, will this work? I am pretty sure it will but I do not want to set this thing up and realize I overlooked something and have to start from all over from scratch.


Solution

  • CREATE TABLE postings ( 
    posting_id INT NOT NULL AUTO_INCREMENT, 
    for_sale LONGTEXT NULL, 
    for_sale_date DATETIME NULL, 
    for_sale_city_id INT NULL, 
    jobs LONGTEXT NULL, 
    jobs_date DATETIME NULL, 
    jobs_city_id INT NULL, 
    PRIMARY KEY(posting_id) 
    

    This isn't what you asked but seeing this structure tells me you need to create a related table (And a lookup table for the values to choose from) instead of doing things this way. If you are listing the same things repeatedly in a table, you need a related table. I would have postings and Posting_type (since you have more than one type you want listed per posting. Something more like this structure.

    CREATE TABLE postings ( 
    posting_id INT NOT NULL AUTO_INCREMENT, 
    posting_description LONGTEXT NULL, 
    Posting_date DATETIME NULL, 
    PRIMARY KEY(posting_id) 
    
    CREATE TABLE posting_categories ( 
    posting_id INT NOT NULL, 
    Category_id int
    Primary Key (posting_id, Category_id)
    
    CREATE TABLE Categories ( 
    category_id INT NOT NULL AUTO_INCREMENT, 
    category_description LONGTEXT NULL, 
    PRIMARY KEY(category_id) 
    

    This gives you the freedom to add as many categories as you like without changing the table structures.