To improve a relation figure for a database - database

This question is based on my plan at the thread.
The following figure shows relations in my database
alt text http://files.getdropbox.com/u/175564/relation-figure.png
I have two "help-tables": questions-subjects and check-moderator. I use the former because one question can have many subjects, while the later because more than one moderator can check a question.
I left out the 1-to-1 number out at the arrows.
The dotted arrow between the tables question and moderator-check indicates that there may be questions which moderators do not check.
This is my first database-project so there are mistakes in the tables.
What would you improve in the table?

User, UserInfo, Moderator and Password are redundant tables that offer no benefit.
They only express 1-1 relationships with User, so there is no need to normalize them into seperate tables:
Make one table:
UserId
Name
Email
PasswordMd5
IsModerator

Reply to FlySwat's answer
I changed my table to the following based on your answer.
alt text http://files.getdropbox.com/u/175564/table-problem-3.png

Related

One-To-Many join table to avoid nullable columns [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 10 months ago.
Improve this question
I'M wondering myself whether am I the first programmer struggling with this problem, but i can't find anything in SO about this.
Point of my question, is it a good idea to make a One-To-Many join table, in order to prevent NULL references.
Let's explain, in our business requirements, we have some activities that causes a payment, i.e. sales, loans, rents, services etc. each activity can have zero or one or more payments.
When designing the DB, we have tables for each activity, Sales – Loans – Rents - Services etc, and a Payment table. The relation between the activities and the payments are one to many, each loan can have many payments, and each rent can have many payments.
But there is a problem, each payment can be a loan or a sale or any other activity, we need to relate it to its corresponding activity. I think about two options:
1) Add some Foreign keys in the Payments table for each kind of activity, LoanID - RentID - ServiceID etc. And make them Nullable, due to a loan is neither a service nor a rent.
I personally don't like this solution, it is very error prone, man can very easy forgot to add the matching FK due to it is Nullable, and then we don't know what this payment is about, we lose the Referential integrity. Although it is possible to overcome this problem by creating some constraint to ensure that there are Neither more nor less than one FK, but it is not so easy to create the right constraint and take into account all possible options, and it is hard to recreate the constraint when adding new FK columns.
Needless to say about the ugliness of such a table. Don't speak about the main issue of letting unnecessary nullable columns in a table.
2) A second solution, to create join tables in between for each kind of activity, called ActivityPayments i.e. LoanPayments etc., that holds the activity ID and the payment ID, like Many-To-Many table.
There aren’t the problems described above, each payment is related to its corresponding activity, there are no referential integrity loss, no Nullable columns.
The problem is however that it enlarges the Database, and adds another layer between the tables, and needs more work when joining in queries.
Has someone any idea?
Another option is to create a supertype table, say Activity, with all of the common attributes:
This should keep the number of tables small, and still allow you to identify the activity type for a payment. Note that this assumes that common attributes exist between the different activities. If that is not the case, the second option you listed is probably the way to go.
Look up the following tags in SO.
single-table-inheritance
class-table-inheritance
shared-primary-key
The info tab on these tags gives you a brief explanation, and the questions grouped under the tag will give you some examples.
Single table inheritance is similar you the solution you presented, and that you are unhappy with. Yes, it does involve NULLS. Generally, user errors here are prevented by the application.
Class-table-inheritance is like the solution offered by AMS. Note that SalesID and LoanID are listed as both a PK and an FK. This hints at the technique of shared primary key. With this, SalesID and LoanID are copies of a value in ActivityID. Again, it's the application layer that does the necessary work to mke sure the copies are right.
in this specific case (not necessarily applicable in similiar situations), we usualy calculate dynamically, in a view/function, each payment for what it was (in chronological order)
in other instances we had one sale table where each product can be a physical product or service or any other for-pay offer. so that limits all debit transactions to one tbale
HTA

SQL Questionaire Database Design (EAV Model) Issue

Im building a friendship site where I try and match users who share similar interests.
I have 25 questions with defined answers(drop down answers) that the user must fill out.
Im using an entity–attribute–value model to store the users id the question id the answered id the user selects.
I then use the count function to see which users have the most matches to my profile.
Current Table Structure
Question Table
Answer Table
Question_Answer_User Table
The problem im running into is I have two question and im not sure where the best place to store them is.
The question is what is your country?
The question is what is your State?
Im not sure if I should store them with the other 25 questions or if i should store them in a three separate tables as seen below.
country table
state table
user_country_state Table
There are going to be alot of answer entries for these 2 questions. For example there are 25 countries the user can answer and a total of 900 states / provinces the user can answer from.
I want to be able to consider the users location as similarity to count but im not sure what the best approach to incorporate this is?
I think the selected country and state should live in the user table, along with the other necessary user information such as name and email address. I don't think it belongs in the Answers table, but it would work there.
For the list of options for the user to select from when setting up his account, storing them in your pre-defined Q and A tables are as good a place as any. It depends, I guess, on how your data and functionality is broken apart so that you aren't crossing responsibility boundaries for the Q&A table storing survey-type answers as well as user-setup answers.

What is the best database design when multiple tables share a common data model? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 2 years ago.
Improve this question
It is very common coming up with the situation where you have multiple tables, let's say Posts, Entries and News and the users can comment in any of them.
The natural way to think this would look like would be something like this:
However, using the parent_type attribute to set up the primary key seems ambiguous to me, because it doesn't really describe clearly to which parent the comment belongs to.
It would seem to me like the clearest way to understand the relationship would be to create an intermediate table for each relationship: posts_comments, posts_entries, posts_news. But then again this doesn't have much sense in terms of database design because you don't really need an intermediate table for a one to many relationship, they are only needed for many to many relationships.
Then maybe a third approach would be to make a different Comment model depending on what it belongs to: PostComment, EntryComment. This would help in understanding better what that comment is for, but I think it is a terrible idea because a comment could just be represented by a single table and you could end up with a bunch of different tables with repeated column while it could just be represented by one table.
So, what is the usual approach for this situation?
I agree that you don't want to create three tables that are almost identical if you can help it. I've seen plenty of databases that do this and it's a pain, because any change is likely to affect all the variations, so you have to make the change three times instead of once, and there are three times as many queries to change. And sooner or later someone will make a change and not know he should make the same change to the other two tables or be in a hurry or forget, and then six months later someone else comes along and wonders if there's a reason why the three tables are subtly different or if this is just carelessness.
But you also don't want to have a column with an ambiguous definition. You especially don't want a foreign key that can refer to different tables depending on the content of a type field. That would be really ugly.
A solution to a similar problem that I used once was to create an intermediate table. In this case, it would be -- I don't know if you have a word that encompasses news, posts, and events, so let me call them all collectively "articles". So we create an article_comments table. It may have no data except an ID. Then news, posts, and events all have a pointer to article_comments, and comments has a pointer to article_comments.
So if you want all the comments for a given news record, it's:
select whatever
from news n
join article_comments ac on ac.iarticle_comments_id=n.article_comments_id
join comments c on c.article_comments_id=ac.article_comments_id
where n.news_id=#nid
Note that with this structure, all FKs are true FKs to a single table. You don't make article_comments point to news, posts, and events; you make news, posts and events point to article_comments, so all the FKs are clean.
Yes, it's an extra table to read, which would slow down queries a bit. But I think that's a price worth paying to keep the FKs clean.
One admittedly clumsy query with this structure would be if you want to know which article a given comment is for if you don't know the type of article. That would have to be:
select whatever
from comment c
join article_comment ac on ac.article_comment_id=c.article_comment_id
left join news n on n.article_comment_id=ac.article_comment_id
left join post p on p.article_comment_id=ac.article_comment_id
left join event e on e.article_comment_id=ac.article_comment_id
where c.comment_id=#cid
and then see which of news, post, and event turns up non-null. (You could also do it with a join to a subquery that's a union, but I think that would be uglier.)
So later. However, you can design model as same below:
#Entity
uid: string
type: string/ (post, new,...)
...
#Comment:
uid: string
entity_id: string
body: String
Other way (only one table)
Entity:
uid: string
parent: string
type: string /post, new, comment, revison,...
metadata: jsonb
Hope useful for anyone!

Should a table with only 1 field of useful data be its own table

Just got a question here about a database table. If the table only has a primary key (identity) and 1 column of useful data, is it okay to be its own table or should it be in the parent table as just the data?
The table is storing Security Questions that the user will set up with they make their account and be used to reset password in the event they want to change password or forgot the password. I have the ID of the question, and the question string in this table.
The reason I have it in its own table is that the same question could be used for many users so why store the question many times in the parent table. Thats my thinking, just wanted a few others' opinions on this.
EDIT: The Security Questions are going to be input by my team, not the user themselves. The user will pick one of the questions to use.
I would suggest this sample design using bridge table:
You can have multiple questions for a user as well as their answers unique. Also, the questions can be same for multiple users.
You must always try to prevent duplicates, that's why your solution is the best.
it will also keep your database smaller. A foreign key with int value is smaller than a string.

design a database for a shopping-cart application? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
I have never designed a database/data-model/schema from scratch, especially for a web-application.
In some recent job interviews, i was asked to 'design' a database for a shopping cart application. Now i am working on a mobile shopping application (retail, uses phonegap) with a backend that needs to store and process product and order info. The scale of this problem is so huge, i don't know where to start. I was hoping for some advise on -
How should I approach such a problem (shopping cart application DB) ? where should i start ?
Are there any common mistakes/pitfalls that i should avoid ?
What optimization/efficiency paradigms should i keep in mind when designing such a DB ?
How should i go about identifying entities in the problem space (products, orders, etc)? how should i derive the relationships between them ?
When a interviewer asks such a question, what exactly is he looking for ? is there something i should/should not say ?
I should also clarify that -
Yes, I am a noob, and my motives are to learn database design AND prepare for upcoming job interviews. I have read DBMS books where they describe individual concepts in detail, but i have no clue how to put those things together and start designing a database.
I have seen other threads on database design. The authors already tend to posses some knowledge on how to break the problem down. i would like to understand the methodology behind doing that.
Links to outside resources, comments, suggestions and anything that will put me on the right track is much appreciated. I hope this thread serves as a learning experience for myself and others.
There can be five tables in database:
CATEGORY this table stores information about products categories of your store and categories hierarchy.parent field of this table stores ID of the parent category.
PRODUCT all products of your store are stored in this table. This table has a foreign key categoryID which identifies ID of the category to which a product belongs.
ORDER this table stores information about all orders made by visitors of your store.
ORDERED_SHOPPING_CART table is tightly connected with PRODUCT and ORDER tables; stores information on customers' orders content.
SPECIAL_OFFER table contains a list of products, which are shown on home page as special offers
A brief answer is the way that i would tackle this problem. Firstly, there are loads of open source or free, web based shopping carts. This means that you can get one, set up the database and then have a good look around what they did.
Ask yourself questions such as, why have they done that? Why is it good? What downside could there be? How would i do it differently? why?
I would try to procure a database design tool that allows you to visualize the database. (like database designer in visual studio or i have one from MicroOlap that does pgsql databases)
Then you need to think about what you need in the database. What is the customer going to do? Buy products! Therefore you need a products table. Without going down the whole route you can see the point. Imagine what is needed, then basically make a table for it.
If you have more than one option for a field in a table, make another table with a relation in it. So if you have a product table and you have a status field. you could have more than one status. (eg out of stock, limited number, big item, expensive) instead of hard coding these fields, make a table and allow the user to add items to the table. then in the product table add a field status_id and link it to the status table
Many - many relationships are useful things to know. (i fell short to this myself.) say you have a component and product tables. The products can be made up of lots of components and the components could be allocated to many products. Create a mediator table. Something like prodcomp( and in this you would have fields like id, prod_id, comp_id, qtyneeded).
Learn to index correctly.
Don't create the database until you have a solid idea of how it will work. this saves time in recreating it later.
There may be more to this, however, i hope i have given you a good start.

Resources