DEV Community

Discussion on: Database constraints considered harmful?

Collapse
 
joelbonetr profile image
JoelBonetR 🥇 • Edited

Didn't read all the comments (sorry if I duplicate a concern here).

A priority in software is robustness.
You can have a bug executing a query (so you'll need to rollback).
You can have a bug in code that alters the data wrongly.

Having a layer to ensure robustness in each step is preferrable, specially when working with users that pay you money.

You can define a model that can or cannot fullfill the formalization (I would expect, at least 1, 2, 3 and BC), but those normal forms are here for a reason plus they imply constraints.

If you really need to do something fast you can just use an ORM (Code First) without specifying any constraint and migrate in a single command instead doing the create tables in SQL commands.

I would anyway encourage you to analyze the business needs for each feature before coding a single line or executing a single query.

Analyzing the business needs you can find inconsistences and you can define and get to know the big picture and the forecast for the roadmap so you can take early decisions. Let's use the email column as example.

You can state that every user will have an email and that emails are unique and it will be a good assumption, but have you asked and defined with client if they are about to let (at any point in the future) the users to change their email from their account?

If it's a yes, simply add an auto increment ID and let the email as required but not as PK.
If it's a no, then you can use email as PK or ignore the client statement and do the thing defined in the line above, it will work anyway and you protected your future yourself from a possible bad day throwing alter tables and sync-ing the code with the new model.

Collapse
 
jonlauridsen profile image
Jon Lauridsen

If I may push back a bit, what does it matter if the client may consider letting users change their email some time in the future? If they say yes, would you design for functionality that isn't needed now? What if they say yes, but never get to it? What if they say yes, but actually what they need next year is something else? What if they say no, but actually meant yes?

We can both agree it's crucial to talk to our customers :), but I'll assert that in the majority of cases a discussion about "any point in the future" is too vague and too theoretical to be of use. I'd rather suggest we build what is needed right now: A User table with an email column. That's it. In data-storage terms I don't care if it's unique or not as I'll handle that in the more flexible code, all I know in data-storage terms is I need to store an email and right now the need is for it to be associated with a User. No constraints to mimic business logic, no concessions for theoretical futures, just what's needed to make the app work right now.

Collapse
 
aarone4 profile image
Aaron Reese

I don't care if it's unique or not as I'll handle that in the more flexible code,

Now you have to write it several times if there are multiple entry paths to the database

all I know in data-storage terms is I need to store an email and right now the need is for it to be associated with a User

So let's model the database with a UserContactMethod table:
ID (Primary Key)
UserID (Foreign key to the User table)
Contact method (enumerated value of phone/email/Twitter handle)
ContactMethodValue

Not a lot of effort to design up front and now caters for 0..N email address against a single User, the same email against multiple users and automatic extendability for other contact methods.. NOT modelling this according to the real world entities will likely result in significant remodeling in the future.