What is the proper name for this table schema? - sql

We have a common database schema that we use for some tables in our system. Them main reason is that we are running a multi-tenant database so not all of our users require the same fields. However, I do not know what the 'proper' name for this type of schema is.
Here's an example of what one of our tables might look like:
ClientID | SurveyID | AnswerKey | AnswerVal
-------------------------------------------
1 | 1 | Fname | Fred
1 | 1 | Lname | Flintsone
1 | 1 | Email | Fred#flintstone.com
1 | 2 | Fname | Mickey
1 | 2 | Lname | Mouse
1 | 2 | Phone | 555-3343
We have been calling them 'Vertical tables', but I don't know if this is correct.

I'd probably refer to is as a Key-Value-Pair table

"What is the proper name for this table schema?"
Crap.
Consider what you would have to do to impose some type constraint on, say, the AnswerValue for email fields.
Consider the effort involved in enforcing possibly required "completeness" constraints requiring some specified set of fields to all be present in some survey.
Consider the effort involved in producing single rows (of which I assume that it can be known upfront which columns need to be included, because you know for which User you are working, thus you know which fields he is interested in).
Consider the effort involved in securing that there is no way for any user to retrieve or manipulate any of the fields he is not interested in.
And I'm sure there's even more ...

Entity-Attribute-Value

I'd call this a Soft-Coding database design.
Sorry to be a bit abrasive, but this kind of design just smells like an anti-pattern.

Coincidentally after looking at this question I came across the answer in this article
Entity-Attribute-Value Table
http://www.simple-talk.com/sql/database-administration/five-simple--database-design-errors-you-should-avoid/

Sorry, but you might want to consider normalizing your table...it can lead to maintainable code (and easier to understand). Use the power of relational tables!

Related

Which query in database is better?

suppose to I have one table and filter by type like wordpress database
// general table
id | title | content | type
---------------------------
1 | hello | some... | post
---------------------------
2 | image | con | image
select * post where type = post
or
// table post
id | title | content
--------------------
1 | hello | some...
select * post
//table image
id | title | content
---------------------
2 | image | con
select * image
so I mean that if I make more table is better or make a single table for my database?
The idea in database design is to have one table per "entity" -- hence the name, "entity-relationship modeling".
It seems reasonable to think that "images" and "posts" are quite different things and should go into their own tables.
That does not mean that "more tables are better". It means that "the appropriate tables are best". In particular, it is generally a bad idea to split an entity across multiple tables.
It is always better to have table per business entity. Business keeps on changing in future, and thus it becomes hard to maintain data in single table. So Posts and Image should be 2 tables. No second thoughts.
the multi table in large project and for small project the general table is better

SQL Server 2012 Query to extract subsets of data

I'm trying to 2nf some data:
Refid | Reason
------|---------
1 | Admission
1 | Advice and Support
1 | Behaviour
As you can see one person might have multiple reasons so i need another table to have the following format:
Refid | Reason1 | Reason2 | Reason3 | ETC...
------|-----------|--------------------|-----------
1 | Admission | Advice and Support | Behaviour
But I don't know how to write a query to extract the data and write it in a new table like this. The reasons don't have dates of other criteria that would make any reason to be in any special order. All reasons are assigned at the time of referral.
Thanks For yor Help.. SQL Server 2012
You are modelling a many to many relationship
You need 3 tables
- One for Reasons (say ReasonID and Reason)
- One for each entity identified by RefID (say RefID and ReferenceOtherData)
- An junction (or intersection) table with the keys (RefID, ReasonID)
This way,
Multiple reasons can apply to one Ref entity
Multiple Refs can have the same reason
You turn repeated columns into rows.

What should a relationships table look like - Need confirmation of my technique

Lets say I have 3 models:
User
Page
Comments
I asked a question based on if I should have each model keep track of its relationships: SQL relationships and best practices
an example of this would be a "Pages" table that states who its author was... The problem seemed to be that if 2 users were the author of the one page, you'd have to add a new specific table called PageRelationshipsWithUsers that might have a reference to the PageID and the UserID that created it and a separate row for the co-author.
Understandably this sounds a bit naff. I would end up with a heck load of relation tables and most likely, it could be replaced with just the one multi-purpose relationship table... So I decided to come up with a relationships table like the following:
Relationships Table New
RelationshipID | ItemID | LinkID | ItemType | LinkType | Status
-----------------------------------------------------------------------------
1 | 23(PageID) | 7(UserID) | ("Page") | ("User") | TRUE
2 | 22(CommentID) | 7(UserID) | ("Comment") | ("User") | TRUE
3 | 22(CommentID) | 23(PageID) | ("Comment") | ("Page") | TRUE
however, I would very much appreciate some input as to how good of an idea laying out my relationships table like this is.
Any thoughts?
Answer was told to me by a work colleague:
Imagine the above relationships table for the model "Book"
A User can Rent a book, so the relation is User -> Book...
But what if he can buy a book too: User->Book....
Ooops, we need a new relationship... and considering this relationship table was supposed to be the 1 size fits all, we now have a requirement to add a new separate table... whoops.
So the answer is NO NO NO. don't, it's naughty. Keep your relationship tables separate and specific.
Your suggestion for a relationship table is not optimal for several reasons:
It's difficult to write queries that join tables through the relationship table, as you will need filters on the ItemType and LinkType columns, which is not intuitive when writing queries.
If a need arises to add new entities in the future, that use different datatypes for their primary keys, you cannot easily store ID's of various datatypes in your ItemID and LinkID columns.
You cannot create explicit foreign keys in your database, to enforce referential integrity, which is possibly the best reason to avoid the design you suggest.
Query performance might suffer.
When normalizing a database, you should not be afraid to have many tables. Just make sure to use a naming convention that makes sense and is self-documenting. For example, you could name the relation table between authors and pages "PageAuthors", instead of "Pages".

is this database designed correctly?

I appeared for an interview which went quite well according to me but not according to the interviewer. He asked me several questions which I answered correctly and 2 practicle questions. One of them was related to database.
The question was something like this
A school consist of several classes and each class studies different subjects which are taught by several teachers. You have to design the database so that one can know that which teacher teaches what subject to what class?
It appeared quite simple and I designed it.
something like:
Teacher table
| ID | Teacher_Name |
-----------------------------
| 1 | Ankit |
| 2 | Jack |
Class table
| ID | class_Name |
-----------------------------
| 1 | First |
| 2 | Second |
Subject table
| ID | subject_Name |
-----------------------------
| 1 | English |
| 2 | stats |
and a master table to combine them all and to know what teacher teaches what subject to which class
Master table
| ID | Teacher_id | class_id | subject_id |
----------------------------------------------------
| 1 | 1 | 1 | 1 |
| 2 | 1 | 2 | 2 |
Just to clear out what I made...I even wrote a select query for the problem even though he didn't asked me to do so.
I am just a beginner at sql so I don't know is this the right way or not but according to me it is quite useful in case I need to make changes to the database. Example addition of a class or a subject.
Now according to him this design will not work at all and He said that I should not even consider my self as a beginner but below the level of beginner.
So please be kind enough to tell me that is this right or not and if its not what is the right way to design the database.
thanks in advance.
It appeared quite simple
That's probably part of the problem. Most database problems appear quite simple. But few of them actually are quite simple.
Not every teacher is qualified to teach every subject in every school. You probably
need a table that pairs teachers with the subjects they're qualified
to teach.
Some entities carry their full identification in their name.
(Subjects seem to; people don't.) Failing to provide a unique
constraint on, say, "subject_name" would be a mistake, regardless of
whether that table has an id number (which might easily be another
mistake).
"Master" isn't a term in the problem domain. That is, if you look at
a college course catalog, you won't find a chapter or section
entitled "Master chapter", or anything remotely like that. But you
will find a section that tells you which subject is offered during each semester, and
that's a clue. In a college, not every course is
available during every semester.
You also need a unique constraint on the "master" table {teacher_id,
class_id, subject_id}.
In that same table, you need overlapping foreign key constraints on
{teacher_id, subject_id} and {class_id, subject_id}.
I could go on. But here's why I wouldn't have hired you.
You were given ambiguous, incomplete requirements. (That's probably not an accident.) You didn't do enough to clarify them.
I am just a beginner at sql
We were all beginners at some point.
Did they want to hire a beginner? If not, that might be another problem.
Except for one glitch it seems fine, the glitch it in the Master Table if you assign a teacher to a class with wrong subject, you cannot put a constraint for that in database, IMHO there shoul be one more intermediary table which maps classes and subjects i-e ClassSubjectMap
----------------------------------------------------
| CSMapID | class_id | subject_id |
----------------------------------------------------
| 1 | 1 | 1 |
----------------------------------------------------
| 2 | 2 | 2 |
----------------------------------------------------
Then this map ID is used in Master table to map teachers with subject, this way a teacher cannot be assigned to teach biology to an engineering class. Except for this other tables seem fine.
About multi-valued-dependency and 4NF
Maybe you don't want to explicitly store information about what subjects can be taught by a particular teacher. Actually, we have a real application on educational process, where we don't store such information, and we haven't needed it badly enough to implement yet. So i guess you can go without it too, given that you weren't provided with requirements to restrict users on assigning teacher to subjects and classes.
What i think you would want to restrict is to have just one teacher for each subject taught to a particular class. So i would go for something simple, like table named "Courses", with columns {id, teacher_id, subject_id, class_id, semester_num}, and a unique constraint on {subject_id, class_id, semester_num}, keeping teacher as an attribute here.

Efficiency between using a string as a table key and splitting it into two tables

I'm contemplating efficiency using a string as a key in a database table. I have an abstract class called Command in my application that has a command key hard coded into the derived class such as "CREATE_ADMIN_USER" or "DELETE_NEWS_POST".
There is some configuration I would like to store in a database such as which roles can execute those commands.
What would be more efficient:
CommandKey | Role
--------------------------
CREATE_ADMIN_USER | GodUser
DELETE_NEWS_POST | Admin
DELETE_NEWS_POST | Editor
OR
ID| CommandKey
--------------------------
1 | CREATE_ADMIN_USER
2 | DELETE_NEWS_POST
ID | Role
--------------------------
1 | GodUser
2 | Admin
3 | Editor
CommandKeyID | RoleId
---------------------
1 | 1
2 | 2
2 | 3
In the case of the first one, the downfall is that you have to store more characters for the command key string. This could become a space problem if you have 1000's of commands and multiple roles for many of them.
The downfall of the second one is that you have to create the join between the 3 tables.
Which one would be preferable between the two (if there is actually a preferable way): use more space OR join 3 tables.
Joins on the primary key of a table are usually fairly cheap. So I would expect the second alternative to be more efficient in most DBMSs, but since you haven't specified what DBMS you're using, it's hard to give a definitive answer.
Also, I believe that the second alternative is far more commonly used, for whatever reason. And I can definitively say is that the second option will be far more manageable in the event that you decide to change the name of a role, or the string of a command key.
For all these reasons, I recommend the second option.