Allow One Column to Relate to Multiple Rows in Another Table [duplicate] - sql

This question already has answers here:
Is storing a delimited list in a database column really that bad?
(10 answers)
Closed 1 year ago.
This post was edited and submitted for review 1 year ago and failed to reopen the post:
Original close reason(s) were not resolved
For an assignment, we are supposed to be "reverse-engineering" a website and try to recreate the database structure. I have all but one column done, and I am not sure how to make it work.
For this assignment, I chose to "reverse-engineer" the Rate My Professors website. I have 4 tables: users, reviews, professors, and schools. In the website, you can save multiple professors, but that is the problem I am having for this... I don't know what datatype to set the "saved_professors" column of the "User" table. I want it to have the ids of each professor in an array, but as far as I know, you can't have the data type as an array (SET and ENUM seem close, but I am pretty sure that those won't work the way I need it to...)
Is there a way to do this? Or should I just set it to a VARCHAR or TEXT (which would just hold a list of the ids in a string)?
Note: This is not about storing a string of ids, I already know how to do that, and I know it's not the best way, that's why I was asking this question specifically... please don't mark it as "duplicate" to Is storing a delimited list in a database column really that bad?... it is a good question/answer, but it doesn't answer my question here.

You need another table.
What you're describing is a many-to-many relationship. A student can save many professors, and likewise a given professor may be saved by many students.
Every many-to-many relationship should be stored as a set of rows in a new table:
CREATE TABLE saved_professors (
user_id INT NOT NULL,
professor_id INT NOT NULL,
PRIMARY KEY (user_id, professor_id)
);
Store just one pair on each row in this table. This means that for each student, there may be many rows in this table.
See also my answer to: Is storing a delimited list in a database column really that bad?

Related

Can There be a Table in a Relational Database that Doesn't Have a Relationship to Any Other Table? [duplicate]

This question already has answers here:
in a relational database, can we have a table without any relation with the other tables?
(5 answers)
Closed 7 years ago.
I have an application in which I store PostId and keywords (Keyword) belonging to a Post in a table named KeywordsForPost. The primary key for that table is the combination of PostId and Keyword. PostId is not unique nor is Keyword.
I needed this implementation because I might need to search for posts regarding the keywords they contain.
I have another table named NewKeywords. The one and only column in that table is Keyword. When a post is created, keywords in that post are inserted into both KeywordsForPost and NewKeywords tables. An operation is applied to the keywords in the table NewKeywords at the user's command so that they no longer become "New keywords". So I delete those keywords after that operation is applied. Currently my NewKeywords table does not have a relationship with any other table. Is this practice justified? Or is there a better practice?
I searched and found this answer.
can we have a table without any relation with the other tables
But did not find it satisfactory.
I also find it different to the question previously asked because it asks a general question, whereas mine is specific. I need to know if a relationship can be added to the table. So far I came up with nothing.
Yes you can. The only thing that could happen is that those table wouldn't have a relationship to other table. i would not say that this is the best way to go, because all depend in your situation. And, like the answer says: It can still be given a relationship later.
Either I'm misreading your question, or there actually is a relationship between NewKeyWords and KeyWordsForPost. It's a value (Keyword) that's common to both tables, and could be used for a relational join. That might be a stupid join that no one would want to do, it might be real slow, for lack of a relevant index, and the keywords aren't a declared key anywhere, but it's still a relationship.
The relationship is inherent in the data, whether you have declared it or not.
I am going to take #rlartiga 's approach guys. I am going to create a Keywords table with the column Keyword and have it as the primary key. Then I am going to have both KeywordsForPost and NewKeywords tables refer to Keyword in Keywords. Thanks for your support guys! Comment if you think this is not the appropriate move.

Should I use an ID? [duplicate]

This question already has answers here:
Surrogate vs. natural/business keys [closed]
(19 answers)
Closed 8 years ago.
I have a table with products like
Products
id
name
styles_id
I also have a table with styles like
Styles
id
name
When I add a style to a product I use a foreign key id value from the Styles table. I do this for a few years now on a lot of projects but I was thinking WHY? It would be a lot easier to get the products if I have a Styles table with a name as primary key and without an id. So I do not have to do a join to get the style name of the product. I see it is done a lot but what are the advantages of the id in the Styles table?
The main advantage is that you can change the name of a product without affecting the references.
You could add multiple names, if, for instance, you wanted to internationalize your database.
Almost every time that I fail to put an auto incremented id in a table, I regret it as some point. That might be when duplicates appear in the table and I want to delete them. That might be when the structure changes in an unexpected way, such as internationalization. That might be when I want to know the last thing that was entered -- auto-incremented id provides that information. Now, I put such an id in almost every table that I create, even in databases where it is painful to do, such as most versions of Oracle.

Data separated by commas inside a field vs new table [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Is storing a comma separated list in a database column really that bad?
This is a problem I often encounter when trying to expand the database.
For example:
I want to keep track of how many users saw a particular article in my website, so in the database I added a views field to the article table. Now, if I wanted to make sure that these are unique views then this is clearly not enough.
So let's say that in my design I can identify a user (or at least a computer) with a single number that's stored along with an IP or something.
Then, if I wanted to keep track of how many unique users saw a particular article which is the best way to go?
To create another table article_views with the fields article_id and
user_id.
To save the user_ids separated by commas inside the views field of the article table.
Never, ever, ever choose the separate-by-commas solution. It is a violation of every principle of database design. Create a separate table instead.
In your particular case, create the table with the PRIMARY KEY on (article_id, user_id). The database will then prohibit the entry of duplicate records. Depending on your SQL engine, you can additionally use INSERT OR IGNORE (or equivalent) to avoid throwing exceptions.
The other solution requires you to enforce the uniqueness in the all applications that touch the data.
Don't use comma separated values. Ever. Create a separate table that links all of those Ids to the article viewed.
Pretty simple design. It will be a table with two columns, both foreign keys. One to the article table and the other to the user table.
Have you considered using
SELECT COUNT(DISTINCT User + IP) As UniqueViews FROM Views GROUP BY ArticleID
If your views table contains duplicates like this records against User and IP (i.e. 10 per cilck per day or something), then COUTN(DISTINCT) will count the distinct occurences of them, not the number of records.

Is a one column table good design? [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 6 years ago.
Improve this question
It it ok to have a table with just one column? I know it isn't technically illegal, but is it considered poor design?
EDIT:
Here are a few examples:
You have a table with the 50 valid US state codes, but you have no need to store the verbose state names.
An email blacklist.
Someone mentioned adding a key field. The way I see it, this single column WOULD be the primary key.
In terms of relational algebra this would be a unary relation, meaning "this thing exists"
Yes, it's fine to have a table defining such a relation: for instance, to define a domain.
The values of such a table should be natural primary keys of course.
A lookup table of prime numbers is what comes to my mind first.
Yes, it's certainly good design to design a table in such a way as to make it most efficient. "Bad RDBMS Design" is usually centered around inefficiency.
However, I have found that most cases of single column design could benefit from an additional column. For example, State Codes can typically have the Full State name spelled out in a second column. Or a blacklist can have notes associated. But, if your design really does not need that information, then it's perfectly ok to have the single column.
I've used them in the past. One client of mine wanted to auto block anyone trying to sign up with a phone number in this big list he had so it was just one big blacklist.
If there is a valid need for it, then I don't see a problem. Maybe you just want a list of possibilities to display for some reason and you want to be able to dynamically change it, but have no need to link it to another table.
One case that I found sometimes is something like this:
Table countries_id, contains only one column with numeric ID for each country.
Table countries_description, contains the column with country ID, a column With language ID and a column with the localized country name.
Table company_factories, contains information for each factory of the company, including the country in Wich is located.
So to maintain data coherence and language independent data in the tables the database uses this schema with tables with only one column to allow foreign keys without language dependencies.
In this case I think the existence of one column tables are justified.
Edited in response to the comment by: Quassnoi
(source: ggpht.com)
In this schema I can define a foreign key in the table company_factories that does not require me to include Language column on the table, but if I don't have the table countries_id, I must include Language column on the table to define the foreign key.
There would be rare cases where a single-column table makes sense. I did one database where the list of valid language codes was a single-column table used as a foreign key. There was no point in having a different key, since the code itself was the key. And there was no fixed description since the language code descriptions would vary by language for some contexts.
In general, any case where you need an authoritative list of values that do not have any additional attributes is a good candidate for a one-column table.
I use single-column tables all the time -- depending, of course, on whether the app design already uses a database. Once I've endured the design overhead of establishing a database connection, I put all mutable data into tables where possible.
I can think of two uses of single-column tables OTMH:
1) Data item exists. Often used in dropdown lists. Also used for simple legitimacy tests.
Eg. two-letter U.S. state abbreviations; Zip codes that we ship to; words legal in Scrabble; etc.
2) Sparse binary attribute, ie., in a large table, a binary attribute that will be true for only a very few records. Instead of adding a new boolean column, I might create a separate table containing the keys of the records for which the attribute is true.
Eg. employees that have a terminal disease; banks with a 360-day year (most use 365); etc.
-Al.
Mostly I've seen this in lookup type tables such as the state table you described. However, if you do this be sure to set the column as the primary key to force uniqueness. If you can't set this value as unique, then you shouldn't be using one column.
No problem as long as it contains unique values.
I would say in general, yes. Not sure why you need just one column. There are some exceptions to this that I have seen used effectively. It depends on what you're trying to achieve.
They are not really good design when you're thinking of the schema of the database, but really should only be used as utility tables.
I've seen numbers tables used effectively in the past.
The purpose of a database is to relate pieces of information to each other. How can you do that when there is no data to relate to?
Maybe this is some kind of compilation table (i.e. FirstName + LastName + Birthdate), though I'm still not sure why you would want to do that.
EDIT: I could see using this kind of table for a simple list of some kind. Is that what you are using it for?
Yes as long as the field is the primary key as you said it would be. The reason is because if you insert duplicate data those rows will be readonly. If you try to delete one of the rows that are duplicated. it will not work because the server will not know which row to delete.
The only use case I can conceive of is a table of words perhaps for a word game. You access the table just to verify that a string is a word: select word from words where word = ?. But there are far better data structures for holding a list of words than a relational database.
Otherwise, data in a database is usually placed in a database to take advantage of the relationships between various attributes of the data. If your data has no attributes beyond its value how will these relationship be developed?
So, while not illegal, in general you probably should not have a table with just one column.
All my tables have at least four tech fields, serial primary key, creation and modification timestamps, and soft delete boolean. In any blacklist, you will also want to know who did add the entry. So for me, answer is no, a table with only one column would not make sense except when prototyping something.
Yes that is perfectly fine. but an ID field couldn't hurt it right?

SQL Structure to Store Surveys and Answers - Build Tables and Queries Based on User Data?

I'm a total newbie when it comes to SQL. I'm making a site in ASP.NET for doing surveys. A privileged admin user will be able to build a survey. Then lots of other people will respond to the survey.
Once I have the set of questions for a new survey, what is the best way to automatically construct a table and an INSERT query to store the responses?
UPDATE
Thanks for the quick responses! I'm still a little unclear on how survey responses would best be stored in this scenario. Would each respondent get a row of the table? And if so, would the columns be "answer given for question k of the survey identified by the entry in column 1"?
You dont want to build a new table for each survey.
Create a surveys table (SurveyID, UserID, Name, etc)
Create a Questions Table (QuestionID, SurveyID, QuestionText, SortOrder, etc)
optionally, Create an Options table, assuming you have multiple choice type questions (OptionID, QuestionID, OptionText, etc)
Then when someone creates a survey, you insert into the Surveys Table, referencing that person's UserID as the foriegn key, then get the newly inserted SurveyID,
Then for each question they add, insert it into the Questions table, using the above SurveyID as the foriegn key.. and so on.
EDIT to answer your edit:
Sorry I should have followed through to cover storing answers as well.
You would want another table called SurveyResponses (ResponseID, Name, etc)
And another table I'll call ResponseAnswers(ResponseAnswerID, SurveyID, ResponseID, QuestionID, AnswerText/AnswerID) Where SurveyID and ResponseID are foriegn keys to thier respective tables, and depending on wether users have multiple choice, or enter an answer, you would either store thier answer as text(varchar) or as another foriegn key to the options table.
You probably don't want to be programatically generating the schema.
Instead, have a table for surveys, for questions (which belong to surveys), for response sets (one per user), and question responses (which belong to the response sets).
I'd think of a couple of options:
Create a one-to-many Survey table and Question table, where each Question has a column DataType that has a code of the response data-type we're expecting, and optionally some other columns / related table of available options, a column that specifies if this question is multi/single choice, mandatory/optional question etc. The Answer table's Answer is serialized/desieralized/indexed/formatted etc. according to the question data-type
Consider using NoSql database to store the survey data in a similar manner
You wouldn't automatically construct the table. The table would be predefined, and the answers would be added to them. I think the best way to get started with ASP.NET these days is to dive into MVC & Linq (http://asp.net/learn)