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

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.

Related

Database Table Design for storing yes, no, and quantity type responses to questions

I have a table that stores answers to checklist questions, where the checklists are in the format of yes, no, not applicable, or resolved.
Table: CHECKLIST_ANSWER
ATTRIBUTE_ID PK, FK
CHECKLIST_INSTANCE_ID PK, FK
TOGGLE_VALUE (1=yes, 2=No, 3=n/a, 4=was a no then it was resolved)
FAIL_REASON
ATTRIBUTE_ID is a foreign key to a table of questions, i.e. Was the part measured within some tolerance?
Now I want to model a checklist that would store quantity responses, i.e. How many incorrect dimensions were found on the drawing?
I feel confident that I can store these questions in my same table as the yes/no/na type attributes, but can I utilize the the same table to store the quantity value? Should I add a new column say QUANTITY_VALUE ? And then either QUANTITY_VALUE or TOGGLE_VALUE would be null depending on the attribute.
Table: CHECKLIST_ANSWER
ATTRIBUTE_ID PK, FK
CHECKLIST_INSTANCE_ID PK, FK
TOGGLE_VALUE (1=yes, 2=No, 3=n/a, 4=was a no then it was resolved)
QUANTITY_VALUE
FAIL_REASON
The goal of this database application is to move paper and excel checklists online and capture into Oracle to give provide more efficient collection of metrics and then better aggreagation of the inputs. Am I asking for trouble down the road by blending two into one table? Or should I create a table, CHECKLIST_QTY_ANSWER
If you have many options, you usually create a seperate table, only with an id and description (or name). To Connect these two tables, you insert a field into the CHECKLIST_ANSWER-Table, and define it as a foreign key, which references to the id (primary key) of the new table, I have mentioned first.
Hope it is clear :)
I don't see any problem with adding the new column to your existing table. I would include a check constraint that required that either TOGGLE_VALUE or QUANTITY_VALUE be null (but not both).
There's no good reason to create a second, nearly identical table, where only a single column varies. In my experience, that tends to lead to more problems than the single-table solution (it's practically an invitation to use dynamic SQL).
I definitely would not re-use the existing column (as suggested in another answer), as that would prevent the use of a foreign key on the toggle value.
If I understand your question correctly you're looking for advice on how to store the new type of answers in your schema?
Since this is a new type of answer you'd need to denote that the format of the data is now different from your y/n/na answer type. You could do this by adding another table CheckListAnswerType and a FK in your CHECKLIST_ANSWER table.
However, your CHECKLIST_INSTANCE_ID could easily indicate that this is a type of checklist that follows a certain answer pattern. I'm not sure about the rest of your schema buy you could have a CHECKLIST_INSTANCE table that specifies it's answer type...
Your TOGGLE_VALUE could follow a numeric scheme for your new answer types and with the a fore mentioned CheckListAnswerType you could and would have to always take this into account when querying the data to make sure you weren't picking the wrong answer type given the question context so that you didn't get a Yes value while looking for your How many incorrect dimensions were found on the drawing? answer.
I would think all of that would be fine, UNTIL you start wanting to store answers of a different data-type. Then it would be time to redesign schema.
TL;DR: If you're using the same data-type for answers then you would be okay re-using the existing schema (column) while adding a way to tell the answer, or question/answer, types apart to query accurately. If you want to store other data-types in TOGGLE_VALUE, implement new schema objects to do so. Don't try and force other data-types into the current schema if you can avoid it. Also if you did this consider renaming TOGGLE_VALUE as it no longer represents a Toggle. answerValue might better fit the new design.

Best practice for a "comment" table in a relational database [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
Assume you want to build a database for some web application. This database already contains many tables and you might have to extend it in the future.
Also, you want the end user to be able to comment any kind of object in the database.
I would like to find a solution for this would be generic enough so that I don't have to extend it each time I add a new table in the database.
I thought of the following:
Table Name: comment
columns:
id : the id of a comment
user_id : the id of the user making the comment
object_table_name : the table where the commented object is
object_id : the id of the commented object in the object_table_name table.
text : the text
date : the date
This table sort of solve my problem, the only thing that troubles me is that the relational aspect of it is rather weak (I can't make object_id a foreign key for instance).
Also if some day I need to rename a table I will have to change all the concerned entries in the comment table.
What do you think of this solution ? Is there design pattern that would help me out ?
Thanks.-
Isn't that cleaner ?
table comment_set
id
table comment
id
comment_set_id -> foreign key to comment_set
user_id
date
text
existing table foo
...
comment_set_id -> foreign key to comment_set
existing table bar
...
comment_set_id -> foreign key to comment_set
You are mixing data and metadata, which is not the best design pattern. They should be separated.
However, since the comments don't seem to be very important anyway, you solution is OK. The worst thing you can end up with is to lose comments on your objects.
Some databases, most notably, PostgreSQL, support COMMENT clause just for the cases like this.
Update:
If you want to comment on individual records in each table, it's OK to have such a table.
object_table_name does not have to change if you rename a table, since it's data, not metadata.
You cannot write a native SQL query that will fetch comments for the record of any table (not known by the moment of the query development), though you can build the dynamic queries to do that.
In this case, you will have to keep your data and metadata in sync (UPDATE the comment table when you RENAME the table they refer to). The first one is a DML statement (changes data), the second one is DDL (changes metadata).
Also make sure that all PRIMARY KEYs have the same types (same as object_id).
Read about EAV.
You can make your whole database like that. But then it will be hell working with that data.
Why don't you want to place a Comment attribute for each database entity which should support comments? This way you can get all the data you need in a single query, and many GUI programs for databases will provide you with full code completion in SQL, which will prevent errors that can easily occur when operating with strings. That way the code is heavily dependent on procedural code, which isn't right for database systems.
You can enumerate the table names in a separate table, so that changes in names do not affect the system in any major way. Just update the enumeration table.
Although you are distancing your self from referential integrity, i can see another way to accomplish what you want.
I generally prefer to keep the comments with the rows to which they apply. Assuming your database efficiently stores empty VARCHAR fields, you shouldn't pay a penalty for this. There isn't really anything to "extend" when you implement this approach, the maintenance of the comment becomes part of the queries you are already using to update the rows.
The only advantage to the single-note-table approach is that it allows easy searches across notes for different kinds of database entries.
Assuming MS SQL, and if the volume is relatively small, as you seem to suggest, then Extended Properties might be worth exploring. I've used them sucessfully in the past and they seem to be a permanent fixture.

Best way to store and retrieve comment replies in sql server

I want to store comment replies in database table.
I have a table to store comments:
comment_id comment_par_id, comment_from comment_text comment date ....
New comment has par_id=0 while the replies has par_id set to comment id to which it was replied.
The nesting is just one level. Reply to a reply also has the same parent id.
Is this the best way to store the replies?
I looked few articles that recommends to create a separate table to store the replies.
Then have a mapping column to point the comment in the main table.
Another alternate is to create a third table that stores the mapping like:
reply_id comment_id
Which is the best way?
No matter what, I only run a query to return the replies for a given comment.
And it is the most running query and must run fast as we have millions of rows in the comment table.
It's a one (comment) to many (replies) relationship, so you should use two tables, with the replies table foreign keyed to the comments table.
If I understand you right, you have an "original post" of some kind, with a set of replies? Similar to how StackOverflow works, with an initial question, with a set of answers? If that is the case, there are a few options. There is the option of using a single table that supports different "types" of records. This choice has the benefit of only requiring a single table, however it also has the drawback of more ambiguity. One has to know that multiple types of records are stored in such a table, making it more confusing.
A better alternative is to have multiple tables, for each "type" of record. This removes the ambiguity, while adding complexity. From a different perspective, different "types" of similar records often have different data, even if some of the data is the same. By using separate tables, it is easier to add distinct traits to each type of comment (original vs. reply), without having to resort to a variety of oddball ways of storing and referencing he extra "unique" data in a single-table system.
Since it is similar to StackOverflow, check out the Schema. Look at the Posts and Comments table.
http://sqlserverpedia.com/wiki/Understanding_the_StackOverflow_Database_Schema

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?

What is the best way to handle this constraint in SQL Server 2005?

I have SMS based survey application which takes in a survey domain, and a answer.
I've gotten requests for detailed DDL, so.... The database looks like this
SurveyAnswer.Answer must be unique within all active Surveys for that SurveyDomain. In SQL terms, this should always return 0..1 rows:
select * from survey s, surveyanswer sa
where s.surveyid = sa.surveyid and
s.active = 1 and
s.surveydomainid = #surveydomainid
sa.answer = #answer
I plan on handling this constraint at the application level, but would also like some database integrity to be enforced. What is the best way to do this? Trigger? Possible in a constraint?
As you are covering 2 tables there is AFAIK only 2 ways to enforce this.
Trigger as you suggested.
Indexed view with unique constraint accross the 3 columns.
As far as reliability is concerned I would go for the Indexed view but the only downside is that it will be difficult to understand by third parties.
It is possible to add a constraint that is implemented in a UDF like this:
alter table MyTable add constraint complexConstraint
check (dbo.complexConstraintFct()=0)
Where complexConstraintFct would be a function containing a query on other tables. However this approach has some issues as check constraints were designed to be evaluated on a single row at a time but updates can affect more that one row at a time.
So, the bottom line is: stick with triggers.
Assuming you are using stored procedures to perform DML operations, you could add a guard clause to the SP that adds answers to surveys to check for the existence of an equivalent answer. You could then either throw an exception or return a status code to indicate that the answer could not be added.
You can't do it at the row level (eg CHECK constraint) so you have to have something that can view all rows
A trigger can send "nice" messages, but they run after the DML statement. You have fine control over processing.
An indexed view prevents the DML statement, but it gives a technical error message. It's an extra object and indexes to maintain.
I think what you're saying is that for any active question, the tuple (surveyDomain, surveyQuestion, surveyAnswer) must be unique?
Or in other words, survey:surveyanswer is 1:1 if the survey is active, even though survey:surveyanswer is set up to be 1:many.
If so, the answer is to change your table structure. Adding a nullable activeAnswerId column to survey will effectively make the relation 1:1; your existing constraint unique SurveyId (or unique SurveyId, SurvetDomainId) will suffice to enforce uniqueness.
Indeed, unless I'm misunderstanding, I'm surprised that Survey has a Question column; I'd expect Survey:Question to be 1:many (a survey has many questions) or even many:many, if a question can show up on more than one survey.
More generally, I suspect the reason that figuring out how to enforce the constraint is difficult and requires "heroics" like triggers or user defined functions, is a symptom of a schema that doesn't accurately model your problem domain.
OP comments:
no, you're missing it. Survey:Answer is 1:n. "Question" is the survey question – Tuple would be (SurveyDomain.SurveyDomainId, Survey.Answer)
You mean that for every domain, there's at most one answer? Again, looking at your schema, it's misleading at best. A SurveyDomain has many Surveys (each of which has a Question column) and a Survey has many Answers? (Schema)
But if the Survey's active bit is set, there should be only one Answer?
Is Survey a misnomer for Question?
It's really not clear what you're trying to model.
Again, if it's hard to add a constraint, that suggests that your model doesn't work.