How to store country and state in sql server - sql-server

I'm creating a video website that similar to youtube except its targets the indie gaming community.
I'm working on the table design and have run into a bit of stumbling block with the location column.
How do major sites design tables for storing location?
Profile table:
ID | username | country | state
0 | jack | US | New York
1 | ted | Canada | Alberta
OR
ID | username | countryID
0 | jack | 1
1 | ted | 2
Regions table:
ID | country | state
0 | United States | Texas
1 | United states | New york
2 | Canada | Alberta
Or is there some other design I missed?

And what about :
profile Table
ID | username | stateID
0 | jack | 1
1 | ted | 2
states table
ID | countryID | state
0 | 0 | Texas
1 | 0 | New york
2 | 1 | Alberta
countries table
ID | country
0 | United States
1 | Canada

I have no idea how "big" websites handle their data, but anyway I think this would be a matter of preference and business requirements, in the first case the table isn't properly normalized as the state depends on the country, and in the other case the model is [almost] properly normalized (the country could be moved to another table). The first option can be faster when doing lookups et cetera but as it breaks the normalized relational model it can lead to issues when inserting/updating the data (as well as additional storage). Personally I would chose to use the second option (and maybe de-normalize it for analytics processing if needed - I would think it very much depends on the amount of data you expect to handle)
A normalized model would look something like:
profile (**username**, state)
states (**state**, country)
countries (**country**)
The example above doesn't use surrogate keys and only illustrate the model; a database implementation of the model would often use surrogate keys such as UserID, StateID and CountryID although if properly normalized they shouldn't be needed as the entities should be primary keys (as they are candidate keys).

Related

Implementing a Model in a Relational Database

I have a super-class/subclass hierarchical relationship as follows:
Super-class: IT Specialist
Sub-classes: Databases, Java, UNIX, PHP
Given that each instance of a super-class may not be a member of a subclass and a super-class instance may be a member of two or more sub-classes, how would I go about implementing this system?
I haven't been given any attributes to assign to the entities so I find this very vague and I'm at a loss where to start.
To get started, you would have one table that contains all of your super-classes (in your example case, there would only be IT Specialist, but it could also contain things like Networking Specialist, or Digital Specialist). I've included these to give a bit more flavour:
ID | Name |
-----------------------------
1 | IT Specialist |
2 | Networking Specialist |
3 | Digital Specialist |
You also would have another table that contains all of your sub-classes:
ID | Name |
--------------------
1 | Databases |
2 | Java |
3 | UNIX |
4 | PHP |
For example, let's say that a Networking Specialist needs to know about Databases, and a Digital Specialist needs to know about both Java and PHP. An IT Specialist would need to know all four fields listed above.
There are two possible ways to go about this. One such way would be to set 'flags' in the sub-class table:
ID | Name | Is_IT | Is_Networking | Is_Digital
----------------------------------------------------
1 | Databases | 1 | 1 | 0
2 | Java | 1 | 0 | 1
3 | UNIX | 1 | 0 | 0
4 | PHP | 1 | 0 | 1
Keep in mind, this is only using a small number of skills. If you started to have a lot of super-classes, the columns in the sub-class table could get out of hand pretty quickly.
Fortunately, you can also use something known as a bridging table (also known as an associative entity). Essentially, a bridging table allows you to have two foreign keys that are primary keys in another table, solving the problem of a many-to-many relationship.
You would set this up by having a new table that associates which sub-classes belong with which super-classes:
ID | Sub-class ID | Super-class ID |
-------------------------------------
1 | 1 | 1 |
2 | 1 | 2 |
3 | 2 | 1 |
4 | 2 | 3 |
5 | 3 | 1 |
6 | 4 | 1 |
7 | 4 | 3 |
Note that there are 'duplicates' in both the sub-class ID and super-class ID fields, yet no duplicates in the ID field. This is because the bridging table has unique IDs, which it uses to make independent associations. Sub-class 1 (Databases) needs to be associated to two different groups (IT Specialist and Networking Specialist). Thus, two different associations need to be formed.
Both approaches above give the same 'result'. The only real difference here is that a bridging table will give you more rows, while setting multiple flags will give you more columns. Obviously, the way in which you craft your query will be different as well.
Which of the two approaches you choose to go with really depends on how much data you're dealing with, and how much scope the database is going to have for expansion in the future :)
Hope this helps! :)

Database Design - Where should user location be stored

Im building a friendship website. The problem I'm having is where should I store the locations of users ( I need to store two variables [country] [state/province]).
The friendship site has a question and answer table currently that stores users attributes such as user religion , users eye color etc...
Is it appropriate to add two more questions to the userAttributes table? (see option 1 below)
What is your country
Whats is your state / Province
OR
Do country and state belong in there own table separate form the userAttributes table. (see option 2 below)
Option 1 - userAttributes Table
Question | Answer
What is your eye color | blue
What is your eye color | green
What country | Canada
What state / province | Alberta
What state / province | Ontario
What country | United States
What state / province | New York
What state / province | Louisiana
What state / province | Georgia
etc ...
Option 2 - ProfileLocation Table
Id | country | province-state
1 | Canada | Alberta
2 | United States | New York
3 | United States | Louisiana
Note : The website will have probably 900 - 1000 provinces / states so this will really fill up the userAttributes Table.
You have two questions, and a large number of answers which are linked to each other. You should store the answers in two tables, which I'll refer to as countries and provinces. The provinces table links back to the countries table so you can extract the data you need easily.
This gives you
Countries
id | Name
------------------------------
1 | USA
44 | United Kingdom
64 | New Zealand
Provinces
id | Country ID | Name
1 | 1 | Oregon
2 | 1 | Arizona
3 | 1 | Kentucky
4 | 44 | London
5 | 44 | Kent
6 | 64 | Waikato
7 | 64 | Wairarapa
(You can fill in the rest)
A simple query will populate a countries drop-down menu on your web page. An AJAX call and a second simple query can populate a provinces drop-down on the fly (or you could send the lists when the page is loaded and use a little Javascript to populate the drop-down from there).

Friendship Website Database Design

I'm trying to create a database for a frienship website I'm building. I want to store multiple attributes about the user such as gender, education, pets etc.
Solution #1 - User table:
id | age | birth day | City | Gender | Education | fav Pet | fav hobbie. . .
--------------------------------------------------------------------------
0 | 38 | 1985 | New York | Female | University | Dog | Ping Pong
The problem I'm having is the list of attributes goes on and on and right now my user table has 20 something columns.
I feel I could normalize this by creating another table for each attribute see below. However this would create many joins and I'm still left with a lot of columns in the user table.
Solution #2 - User table:
id | age | birth day | City | Gender | Education | fav Pet | fav hobbies
--------------------------------------------------------------------------
0 | 38 | 1985 | New York | 0 | 0 | 0 | 0
Pets table:
id | Pet Type
---------------
0 | Dog
Anyone have any ideas how to approach this problem it feels like both answers are wrong. What is the proper table design for this database?
There is more to this than meets the eye: First of all - if you have tons of attributes, many of which will likely be null for any specific row, and with a very dynamic selection of attributes (i.e. new attributes will appear quite frequently during the code's lifecycle), you might want to ask yourself, whether a RDBMS is the best way to materialize this ... essentially non-schema. Maybe a document store would be a better fit?
If you do want to stay in the RDBMS world, the canonical answer is to have either one or one-per-datatype property table plus a table of properties:
Users.id | .name | .birthdate | .Gender | .someotherfixedattribute
----------------------------------------------------------
1743 | Me. | 01/01/1970 | M | indeed
Propertytpes.id | .name
------------------------
234 | pet
235 | hobby
Poperties.uid | .pid | .content
-----------------------------
1743 | 234 | Husky dog
You have a comment and an answer that recommend (or at least suggest) and Entity-Attribute-Value (EAV) model.
There is nothing wrong with using EAV if your attributes need to be dynamic, and your system needs to allow adding new attributes post-deployment.
That said, if your columns and relationships are all known up front, and they don't need to be dynamic, you are much better off creating an explicit model. It will (generally) perform better and will be much easier to maintain.
Instead of a wide table with a field per attribute, or many attribute tables, you could make a skinny table with many rows, something like:
Attributes (id,user_id,attribute_type,attribute_value)
Ultimately the best solution depends greatly on how the data will be used. People can only have one DOB, but maybe you want to allow for multiple addresses (billing/mailing/etc.), so addresses might deserve a separate table.

PHP deleting records on page without deleting in Database

I would like to check whether
if there any ways to delete the record in the page, without deleting records in database?
I'm doing a shopping cart and would like to have the user to be able to view back their past transaction.
Is there any ways that I could delete the records in the cart, after I check out? And also able to view the past transaction.
I've not done any code yet,
just seeking for advices
Yes. You can have a database with the products, a second with your users and a third one to associate the users id with the products id they purchased.
You can never delete a item from the database. You can include a information of status like 'active/inactive' instead of actually deleting it.
Edit
When you have products in cart, usually the list is saved in cookies, temporarily by browser or javascript or another way (if your country forbid cookie, you have to search for alternatives). Once the purchase is finished, the cart list is saved in database and the cookie or whatever is cleared. You do not delete anything from database.
Example
Users/ buyers database
+--------+----------+
| idUser | nameUser |
+--------+----------+
| 1 | Antony |
| 2 | Betty |
| 3 | Carl |
+--------+----------+
Products database
+-----------+--------------+-------+-----------+
| idProduct | nameProduct | price | available |
+-----------+--------------+-------+-----------+
| 1 | Apple dozen | 10.00 | yes |
| 2 | Banana unity | 20.00 | yes |
| 3 | Cherry kg | 30.00 | yes |
+-----------+--------------+-------+-----------+
Active/ Inactive Example
Notice here how you don't need to delete any record ever. You can create a option such like available to products like example above. So you can just set it to yes or no. So you just code your front-end to show products which available is yes while your back-end can see all of them. It is very useful. In a case when your product has tens of information and you delete the product, but it will only be unavailable for 3 weeks, you would lose a great time deleting and typing and saving everything again. It is much better just set it to show or not to show. (Some stores just opt to show everything, but alert when it is unavailable).
Have in mind that it isn't a rule for everything. Always look for the best perfomance. If you have a database with 10k unavaiable products that will never be available again and you just have 2 available itens, it would be a little nosense keep all this records alive.
About prices historic
Prices Historic Database
+--------+--------+-----------+-----+----------+----------+
| idItem | idUser | idProduct | qty | subtotal | date |
+--------+--------+-----------+-----+----------+----------+
| 1 | 1 | 1 | 2 | 20 | 10/10/13 |
| 2 | 1 | 2 | 1 | 20 | 10/10/13 |
| 3 | 2 | 1 | 1 | 10 | 11/12/13 |
| 4 | 2 | 2 | 1 | 20 | 11/12/13 |
| 5 | 2 | 3 | 1 | 30 | 11/12/13 |
| 6 | 1 | 1 | 1 | 10 | 01/06/14 |
+--------+--------+-----------+-----+----------+----------+
It is always good to have a unique identification for each row on database. Well, in most cases. Its is not very readable for humans, but it fits well for machines. Check this database. The line 1 and 2 say us that user 1 bought on 10/10/13 the item with id 1 x 2 and item with id 2 x 1. Translating: Antony bought 2 Apple dozen and 1 Banana unity.
In this database you could filter rows by user and them group by Date. You would see that Antony bought more Apples in 01/06/2014.
I personally like to save the subtotal on database. If in 2015 the apple price raise to 15.00, you and the user can see he paid 10.00 in 2013 and you can do reverse calc to get the individual price.
If you could read this thid database well, you see Betty bought one of each item in 11/12/13 and Carl has never bought anything.
I believe and hope it will help you.
It is just a simplified example on how the logic works. I matched the product directly with buyer, but most stores usually add a 4th database just to list Orders. So you relate Users with Orders and Orders with Products. Everything has its advantages and disadvantages

How to design database, one table for all product type or each table for each product type?

I start new e-commerce web application (pet project) that sale both t-shirt and shoe. My store has only free size T shirt so t-shirt has only color column while shoe has columns for size and color.
Now it's time to create table to store that data, I want to know is it good to create separate table for shoe and t-shirt or it's better to keep all of them in one table?
If it has a better idea to store such data, please let me know.
You definitely don't want to create a Shoe table and a TShirt table. Your shop might grow, and one day you'll have a thousand such product tables. Writing SQL for that would be a nightmare. Plus, you might have different kinds of t-shirts eventually, some with color, some with size and color, and so on. If you create a new table for each, you'll lose track of them quickly, and if you don't, why have separate tables for t-shirts and shoes, but not for one-size t-shirts and multi-size t-shirts?
While designing your database, you should be asking yourself: what are the entities in my realm? what are the things that never change and are uniquely identifiable? In a shop, a particular item that can be sold at a particular price is one such entity. So you might have a products table that has a key for each particular item you sell, and maybe a name, a type, a size and a color column:
item
id | type | name | size | color
------------------------------------
1 | shoe | Marathon | 9 | white
2 | shoe | Marathon | 9 | black
Looking at this table, you notice that we have two entries for the highly successful Marathon running shoe, and that seems to be a normalization violation. Indeed, you probably have two entities a shippable item and a catalog product. The shoe "Marathon" is probably something that has one picture and one description in your store, followed by a "available in the following colors and sizes:" line. So now you have two tables:
product
id | type | name | supplier | picture | description
--------------------------------------------------------------------------------------
1 | shoe | Marathon | TrackNField Co. | marathon.jpg | Run faster than light!
2 | tshirt | FlowerPower | SF Shirts | fpower.jpg | If you're going to San Francisco...
item
id | product_id | size | color | price
--------------------------------------
1 | 1 | 9 | white | 99.99
2 | 1 | 9 | black | 99.99
3 | 2 | | blue | 19.99
The "type" column in the product table can be a tricky one. You'll probably want to display products by category, let the user click on "shoes" and get all products with type "shoe". Easy so far, but eventually someone will mistype an entry "sheo", and then you can't find that product under shoes anymore. So it's better to separate the categorization from the products, for example by having a product_type table:
product_type
id | name
---------
1 | shoe
product
id | type_id | name | supplier | picture | description
--------------------------------------------------------------------------------------
1 | 1 | Marathon | TrackNField Co. | marathon.jpg | Run faster than light!
with a reference to the type in the product table. That's ok as long as your type hierarchy stays shallow, but what if you want to have subcategories, like "sneaker", "basketball shoe", "suede shoe", and so on? One shoe might even belong to several of these subcategories. In that case you can try this
category
id | name | supercategory_id
------------------------------------
1 | shoe |
2 | running shoe | 1
product_category
product_id | category_id
------------------------
1 | 2
product
id | name | supplier | picture | description
--------------------------------------------------------------------------------------
1 | Marathon | TrackNField Co. | marathon.jpg | Run faster than light!
And if you want to display multiple hierarchies of categorizations (as most big ecommerce sites do these days), you'll have to come up with something even more sophisticated.
Keep them all in one table and have a type field. The reason to do it this way is so that your data structure is scalable: i.e. if there is a new type of product then instead of adding a new table and having to drastically change your application code, you just use the same table and simply add a type.
if you don't want make it to complex you can keep all of them in the same table and create another table called "ProductType" that tells you if it is a shoe or a t-shirt.
The relationship will be One-To-Many on the "ProductType" side as you can have the same type of product associated with more then one record on the product table(where you store all your products)

Resources