How to design a database table from a form? [closed] - database

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 6 years ago.
Improve this question
I'm learning how to design databases, and i've been ask to create the table that will hold this form: Medical History I'm learning to use Django/Python i've already made the markup in HTML and CSS, but I don't think that making each question on the form an column would be the best approach. For example in the family history i've thought of making it a separate table, while in the review of systems i want to make each to be a set.

A pragmatic approach is to define tables based on the following criteria:
1) easy to select data from them (not to obtain many JOINs or convoluted queries that require ORs or strings splitting)
2) easy to understand (each concept maps to one table)
=> usually, normalized structures do the trick here
Of course, above are challenged in high transactional environments (INSERTs, UPDATEs, DELETEs).
I would assume then your case has moderate INSERTs, but more SELECTs (reports).
For Family history section I would normalize everything:
DiseaseType
DiseaseTypeId
Code -- use to separate from a name that can change in time
Name -- breast cancer, colon cancer etc.
CollateralOption
CollateralOptionId
Code -- I would put UNIQUE constraints on Codes and Names
Name -- no, yes, father
FamilyHistory
FamilyHistoryId INT PK IDENTITY -- this may be missing, but I prefer if I use an ORM
PatientId -> FK -> Patient
DiseaseTypeId -> FK -> DiseaseType
CollateralOptionId FK -> CollateralOption
Checked BIT -- you may not define this and have records for Checked ones.
-- having this may put some storage pressure
-- but prevent some "stuffing" in the queries
These structures allow to easily COUNT number of patients with colon cancer cases in their family, for example.
Shortly put: if there is not serious reason against it, go for normalized structures.

I don't see any advantage to perform any design tricks on this data structure. Yes, making a boolean attribute of each of your checkboxes, and a string attribute of each of your free texts, will lead to a high number of attributes in one table. But this is just the logical structure of your data. All these attributes are dependent on the key, some person id, (or at least that's what I assume, as a medical layman). Also, I assume that they are independent of each other, i.e. not determined by some other combination of attributes. So they go to the same table. Putting them on several tables won't gain anything, but will force you to do lots of joins if you query on different types of attributes (like all patients whose mother had breast cancer and who now have breast lumps).
I don't know exactly what you mean by making sets of some attributes. Do you mean to have just one attribute, and encode the sequence of boolean values e.g. in one integer, like 5 for yes-no-yes? Again that's not worth the trouble, as it won't save any space or whatever, but will make queries more complicated.
If you are still in doubt, try to formulate the most frequent use cases for those data, which will probably be typical queries on combinations of these attributes. Then we might see whether a different structure would make your life easier.

Related

Coupling and Cohesion in database design [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 6 years ago.
Improve this question
Say there are two modules users and status. I split these modules in following 2 cases
Here is case-1
Here is case-2
I am trying to understand which database design lowly coupled and should be adopted according to the Software Engineering Design principals? Particularly interested to have comments that which approach is better by considering re-usability. I mean in future which approach can be re-used easily & effectly to any other software design
Both your cases have consistency issues rather than coupling/cohesion issues.
First, both your cases allow for a department to have a limitless amount of statuses. This might not make sense if, for instance, the status represents whether the department is open or closed. If departments may only have 1 status at any given time, your primary key for an status must be dept_id (in which case it should be within the departments table as a foreign key to the table with the available statuses instead), this may be incorrect depending on what you are modelling. The second case, however, is worse for consistency because it allows you to have an unlimited amount of values for the variable status (There is no table to define the valid values for status, so this case allows you to have typos even, for instance a department with status "opne" instead of "open")
Secondly, the users table has no relationship with the rest of the data, which may not make sense again (users can't be members of any department, etc). In the first case, users have no status and in the second case it is related to an status table... Neither case (for the users table) has more or less coupling than the other (because it has no relationship with anything else in your model), but you need to check whether you want users to have an status (and what is that status, whether it should be selected from a fixed list of values or not).
We don't have much to go on about analyzing coupling/cohesion in both of your cases. You must better understand what you are trying to model and should first worry about ensuring consistency.
Here's an short but interesting blog post about coupling/cohesion if you want to read some: https://thebojan.ninja/2015/04/08/high-cohesion-loose-coupling/
Hope it helps!

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!

Database design: Likes table [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 months ago.
Improve this question
I got two tables (for now):
Topic
Post (post is a comment for a topic)
I want to add the option to Like those objects.
so I thought about creating one table of Likes and using enum to indicate which object was liked (including the object's id of course).
by the way, if I choose this option, should it be an enum or another table represent all the objects:
id object_name
1 Topic
2 Post
another option is to create likes table for every object .
what is the best practice to take?
I think creating a separate table for each object is better.
I don't see what you gain if you use only one table. You can't use foreign keys properly also in one table.
I mean you can't add a column object_id to your table, because you do not know the table to which it will point to. In this case you have two add two columns, topic_id and post_id. Always one of the two will be NULL.
Just create another table for the likes:
tbl_posts_likes (likeID, userID, postID, like = 1, unlike = -1)
then you could write a subquery like:
SELECT SUM(like) as likeCount, SUM(unlike)
FROM tbl_posts_likes
GROUP BY postID
WHERE postID= posts.postID
Depending on how you are tracking 'likes', I would recommend adding another table called likes to the following effect:
likes (like_id, like_type)
From this point, you would simply COUNT() the number of 'likes' for each like_type (topic/post) as each time someone likes either a topic or a post, a record would be inserted. However, if you plan to track 'likes' by user, you would need to add another column for user.
If you wanted to track the individual posts or topics, you would set up a table for each object and create a foreign key contraint for the topic or post ID.
topic_likes (tl_id, topic_id)
post_likes (pl_id, post_id)
The design above would create an entry for each like. If you are only concerned with the total number of likes for each object, you could set up something like so:
likes (like_id, like_type, likes)
A table for likes is a overkill. When does anyone need to check who liked who's post. Very rarely. Its better to just maintain a count of likes and unlikes in the post table, and maintain a likes table only for archive and audit purpose. Basically for all regular operations use the counts, for audit needs.
This will prevent doing joins to calculate # of likes. Frankly accuracy of likes and unlikes is not that crucial. 99% accuracy is good enough. And consistency between API calls may cause a issue, that is very rare. Only on high load.
I also find doing operations like SUM on a database server is very costly. JOIN and then SUM, too painful and time consuming. Instead move the operation to the compute. On the API do the ++ or --. That will take the load off the DB for useless operations like this.

What is data normalization? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
What exactly does database normalization do?
Can someone please clarify data normalization? What are the different levels? When should I "de-normalize"? Can I over normalize? I have a table with millions of records, and I believe I over-normalized it, but I'm not sure.
If you have million columns you probably under-normalized it.
What normalizing means is that
every non-key attribute "must provide
a fact about the key, the whole key,
and nothing but the key."
If you have a column that depends on anything but the key, you should normalize your table.
see here.
Added to reply to comment:
If you have ProductID | ProductType | ProductTypeID, where ProdcutTypeID depends only on ProductType, you should make a new table for that:
ProductID | ProductTypeID and on the other table: ProductTypeID | ProductTypeName .
So to answer your question, pertaining to Product isn't accurate enough, in my example at the first case, I was pertaining to the Product as well. All columns should pertain only to ProductID (you may say you only describe product, but not describing anything else, even if it's related to product - that's accurate).
Number of rows, generally speaking isn't relevent.
Normalization is about reducing data duplication in a relational database. The most popular level is third normal form (it's the one described by "the key, the whole key, and nothing but the key"), but there are a lot of different levels, see the Wikipedia entry for a list of the main ones. (In practice people seem to think they're doing well to achieve third normal form.) Denormalizing means accepting more data duplication, typically in exchange for better performance.
As others said Database normalization is about reduction of data duplication and more generic data models (that can easily answer to queries unexpected at design time). Normalisation of a database is allow a formal enough process. When you are experimented you mostly follow data analysis methods and get a normalized database at the end.
Normalizing database is usually a good idea, but there is a catch. In many case it involve creation of new tables and JOIN relationships between tables. JOIN is known to have a (very) high performance cost at runtime, henceforth for big volumes of data you may want to denormalize.
Another cost may also be the need to write more complex requests to access to the data you need and that can be a problem for SQL beginners. The best idea is probably to stick with normalization anyway (Third Normal Form is usually enough, as there is several levels of normalization as others said) and to become more skilled with SQL.

When to split up models into multiple database tables? [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
I'm working with Ruby on Rails, but this question I think is broader than that and applies to database design generally.
When is it a good idea to split a single model up into multiple tables? For example, assume I have a User model, and the number of fields in the model is really starting to add up. For example, the User can enter his website, his birthday, his time zone, his etc etc.
Is there any advantage or disadvantage to splitting up the model, such that maybe the User table only has basic info like login and email, and then there is another table that every User has that is something like UserInfo, and another that is UserPermissions, and another that is UserPrivacySettings or something like that?
Edit: To add additional gloss on this, most of the fields are rarely accessed, except on pages specific to them. For example, things like birthday are only ever accessed if someone clicks through to a User's profile. Furthermore, some of the fields (which are rarely accessed) have the potential to be extremely large. Most of the fields have the potential to be either set to blank or nil.
Generally it is a good idea to put things which have a one-to-one relationship in the same table. Unless your userbase includes the Queen or Paddington Bear, a user has just one birthday, so that should be an attribute of the USERS table. Things which have a one-to-many relationship should be in separate tables. So, if a user can have multiple privacy settings by all means split them out.
Splitting one table into several tables can make queries more complicated or slower, if we want to retrieve all the user's information at once. On the other hand if we have a set of attributes which is only ever queried or updated in a discrete fashion then having a separate table to hold that data is a sound idea.
This would be a situation for analysis.
When you find that a lot of the fields in such a table are NULLs, and can be grouped together (eg. UserContactInfo), it is time to look at extracting the information to its own table.
You want to avoid having a table with tens/hundreds of fields with only sparsely entered data.
Rather try to group the data logically, and crete the main table containging the fields that are mostly all populated. Then you can create subsets of data, almost as you would represent them on the UI, (Contact Info, Personal Interest, Work Related Info, etc) into seperate tables.
Retrieving a row is more expensive if it has many columns, especially if you usually need just some of the fields. Also, hosting stuff such as the components of an address in a separate class is a case of DRY. On the other hand, if you do need all fields of an object, it takes longer to execute a compound query.
I would normally not bother to distribute classes over several tables just to make the code more readable (i.e. without actually reusable parts like addresses).

Resources