Is it good to use check constraints for business rules - sql

Currently we are using check constraints for business rules implementation, but I want to know if we should implement business rules in SQL or in the business logic layer (C#). I have searched on the net and found that check constraints are good to use.
Please let me know if someone knows more detailed information about it. One more thing is that the data can be pumped into my database using a mobile application and also using a web application.

YES it is good!
You should really always check your business rules both in your app code (in the business layer), but if ever possible also in your database.
Why? Imagine someone manages to submit some data to your database without using your app - if you have your checks only in the app, those checks are not being applied.
If you have your checks on the database as well, you can make sure the data in the database conforms to at least those simple checks that can be formulated in SQL CHECK CONSTRAINTS.
Definitely use those! You need to try and keep your data quality as high as possible - adding referential integrity, check constraints and unique constraints and so forth on the database helps you do that.
Do not rely on your app alone!

Yes, check constraints are a valid tool for business rules.
But are you sure you need to use check constraints, or use a supporting table with a foreign key relationship? If you find yourself defining similar check constraints in various places - the answer is yes, this should definitely be a supporting table.
Data integrity is key; there's not much value to a system that will allow a person to store something that is not per business rules if the application is circumvented. It also makes life a lot easier if the logic is in the database for situations where the original app is in C# and the higher-ups decided the market needs a Java/Ruby/Python/etc version.

You should definitely use CHECK constraints where possible, but I also wouldn't over do it. If there is no possibility of getting data into your database without using your applications, you can be safe with minimal CHECK constraints and heavy business validation.
It can be fairly difficult to define strict business rules in SQL. Stick to data validation in the database, and actual business rules in your application.
Also, try to arrange your schema in such a way that makes it difficult to enter bad data with foreign keys and the like.

As more "intelligent" is your database, more secure will be the integrity of the data it contains. So, yes, I think this is good and important to implement it.
This puts in lots of advantages: you can ensure that your data will be secure if there are more than one application modifying the data (ex: C# app + Web app + Mobile app ...) and it allow you to make less work in those "secundary" applications. If the database do all the work, apps are only a frontend for the database.
It will be easier in the future to migrate the applications, but will be more dificult to migrate the database. This is an important decision.

Depends on the constraints
It depends on the constraints
You should also try to avoid (if possible) having the same constraint checked in 2 places - this would imply there is duplicated code in your system, leading to unnecesary complexity.
There are some constraints that can and should be applied in the database, for example foreign key constraints and uniqueness. The database will be able to apply these quickly and efficently.
Other more complex "business" constraints are better applied in the business logic layer. Examples of these might be "customer must have a validated email address before allowing a purchase". These would be complicated and onerous to apply in the database - you'd run the risk of coding your system in SQL which is A Bad Idea.

C#. It's much easier to reuse logic in C# than SQL (in my experience) and generally maintain.

Related

Model validation logic in the database via constraints. Good idea, bad idea, or not worth it?

It's always rubbed me the wrong way to write code in my model's clean method to validate various constraints on the data when these same constraints aren't also present in the database.
After all, the database already has constraints for some of my data, like NOT NULL.
So, I've been writing RawSQL migrations that ADD CONSTRAINT some_logic in my most recent project that matches whatever logic I have in my clean() method.
It works OK, but it isn't an insignificant task to remember to add these constraints, add tests for these migrations, and update them when my model changes. Also, of course, I'm violating DRY by writing code in two places to do the same thing.
Should I give up this quixotic quest?
This is by no means a comprehensive answer, but at least I wanted to give my opinion.
There has been many frameworks that have pushed the idea of removing the constraints from the database, in order to check them at the application level. The idea seemed nice to me at first (in the early 2000s) but after some years I came to the (very personal) conclusion that this is a bad idea.
I think, to me it boils down to two things:
Data survives much longer than the applications. Whole systems go obsolete, but the data survives many more years. Sometimes the application is replaced, but the database is stil the same one.
The application is not as reliable when it comes to validate data. I'm talking about programming defects here. One version of the app may work well and then the next one has a bug. It may be that one developer moves out of the company, then the new replacement -- who doesn't know as much -- changes the app with disastrous consequences. All that time a simple database constraint (that is usually very cheap to implement) could have enforced data quality.
Yep, I'm a fan of strict database constraint. Nevertheless, this doesn't mean I'm against application validations. These ones can show much nicer error messages.
If writing too much logic in clean() feels dirty, an in-between solution would be to use Django's built-in validators directly on your model fields.
The validation logic isn't saved in the database, but it is tracked in migrations. Like clean() logic, Validators require you to call Model.clean_fields(), but a ModelForm does this automatically.
You can also dig into django-db-constraints. The library might help do what you're looking to do, and the source code might help you roll a solution that fits your needs.

Your experience with foreign keys

So I am interested in the "use percentage" of FKs in the industry. Do you use FKs in your projects, are there cases when you don't use them? I worked in two companies so far and one of them is quite a leader in the industry and they solve that part of "integrity" in their app layer, so I was interested what is the "ratio" of of DBs with and without FKs.
I don't have a use percentage for you, but I can tell you it's too low. Yes, I do use FK constraints where possible, and I design my databases to support their use. In cases where I didn't or couldn't use them, I frequently ended up having to repair data. Integrity in the app isn't good enough - the app usually isn't the only user of the database, there's often external conversion/integration apps, and don't forget the DBA who needs to be able to modify data and schema without breaking it. Even if the app were the only user, I'd rather let the DBMS handle integrity than complicate my code by reinventing that functionality.
Below is a link to a horror story of a company that did NOT bother to use foreign keys on (one of) its databases :
Find GUID in database

Best practice: should I use FK on DB using nHibernate/FluentNhibernate?

So far I always enforce my DB with FK relationship. Things changed yesterday while mapping some classes with FluentNhibernate. My mapping didn't work and I discovered that's the issue was because of the order FN create the query.
Now a question arise: should I keep enforcing data with FK or it's better to avoid it since I focus on domain classes instead of sql queries?
Thanks
To my knowledge, it will be far better to keep your database consistent,
cause you may not be the only one who works on this DB in future,
and maybe someone else have access to the DB and do sth that could corrupt your data consistency
and as a result your application also doesn't behavior in the way you expect because of assummed conditions that no longer hold.
Letting Fluent/NH create your database during development is fine, but when it goes into production you really should check all the foreign keys, index's, etc etc and then only do scripted changes there on after.
Keep your database consistent, maintain referential integrity.
If a tool you are using breaks as a result there is bound to be a workaround. However if you lose referential integrity to use nhibernate - what happens if you decide to use a different ORM? You will have a dodgy database and who's to say that the next ORM in line will like that?
Its like a separation-of-concerns question, each chunk of your application should be designed to be robust enough to survive if another chunk is changed or removed - so don't change good database practice simply to make a product that is layered above it play nicely.
Using a domain-driven approach , or model oriented approach where the DB is merely seen as an 'implementation-detail', does not mean that you should ignore the integrity of your data.
I see no reason why you should drop foreign-key (and other) constraints from your database.
The database is more then just a storage for your data. It's task is also to guard the integrity of it.
It is perfectly possible to combine the 2 worlds (domain driven and relational database) with NHibernate. Make sure that the 2 areas focus on what they're best at. And, the database is best at storing data and making sure that the data remains valid / integer.

Flexible Persistence Layer

I am designing an ASP.NET MVC 2 application. Currently I am leveraging Entity Framework 4 with switchable SQLServer and MySQL datastores.
A requirement recently surfaced for the application to allow user-defined models/entities to be manipulated. Now I'm unsure if a SQL/relational database is appropriate at all; instead of adding/removing 'Employee' objects, for example, the user should be able to define an 'Employee' and what properties it has - effectively adding/removing tables and columns on the fly, at runtime.
Is SQL unsuitable for this? Are there options which allow me to stay within a relational database structure and still satisfy this requirement? Within the Entity Framework, can I regenerate .edmx files 'on the fly' or are there alternatives which achieve similar goals?
I've looked briefly at other options like 'document-based' dbs and 'schema-free/no-sql' dbs, such as MongoDb. I've also looked at some serialization formats such as Google's Protocol Buffers, JSON, and XML. From your experience, are any of these particularly suitable for this purpose? Serialization performance is not a big concern.
The application is in its infancy and I have no time constraints. Essentially I am free to rewrite it as I please, so if scrapping and starting over is a better alternative, I am very open to this. What are your suggestions? Thanks in advance!
Before looking at options I'd suggest (if you have not already done it :-) that you need to get a clear definition of exactly what users will be able to define. Once you have that you can then deduce an idea of the level of flexibility needed and therefore the type of data store needed to do the job.
One other word of advice would be that if they clients demand to be able to create anything any way they want - walk away. I've dealt with clients and users at all levels and one thing that is guaranteed is is that users have no interest if the effective and efficient design of data and therefore will always reduce the data to a pile of poo through shear neglect.
You need to set some boundaries so that the data store behind the system maintains some integrity.

database relationships

does setting up proper relationships in a database help with anything else other than data integrity?
do they improve or hinder performance?
As long as you have the obvious indexes in place corresponding to the foreign keys, there should be no perceptible negative effect on performance. It's one of the more foolproof database features you have to work with.
I'd have to say that proper relationships will help people to understand the data (or the intention of the data) better than if omitting them, especially as the overall cost is quite low in maintaining them.
Their presence doesn't hinder performance except in terms of architecture (as others have pointed out, data integrity will occasionally cause foreign key violations which may have some effect) but IMHO is outweighed by the many benefits (if used correctly).
I know you weren't asking whether to use FKs or not, but I thought I'd just add a couple of viewpoints about why to use them (and have to deal with the consequences):
There are other considerations too, such as if you ever plan to use an ORM (perhaps later on) you'll require foreign keys. They can also be very helpful for ETL/Data Import and Export and later for reporting and data warehousing.
It's also helpful if other applications will make use of the schema - since Foreign Keys implement a basic business logic. So your application (and any others) only need to be aware of the relationships (and honour them). It'll keep the data consistent and most likely reduce the number of data errors in any consuming applications.
Lastly, it gives you a pretty decent hint as to where to put indexes - since it's likely you'll lookup table data by an FK value.
It neither helps nor hurts performance in any significant way. The only hindrance is the check for integrity when inserting/updating/deleting.
Foreign keys are an important part of database design because they ensure consistency. You should use them because it offers the lowest level of protection against data screw ups that can wreck your applications. Another benefit is that database tools (visualization/analysis/code generation) use foreign keys to relate data.
Do relationships in databases improve or hinder performance?
Like any tool in your toolbox, the results you'll get depend on how you use it. Properly specified relationships and a well-designed logical database can be an enormous boon to performance -- consider the difference between searching through normalized and denormalized data, for example.
Depending on your database engine, relationships defined through foreign key constraints can benefit performance. The constraint allows the engine to make certain assumptions about the existence of data in tables on the parent side of the key.
A brief explanation for MS SQL Server can be found at http://www.microsoft.com/technet/abouttn/flash/tips/tips_122104.mspx. I don't know about other engines, but the concept would make sense in other platforms.
Relationships in the data exist whether you declare them or not. Declaring and enforcing the relationships via FK constraints will prevent certain kinds of errors in the data, at a small cost of checking data when inserts/updates/deletes occur.
Declaring cascading deletes via relationships helps prevent certain kinds of errors when deleting data.
Knowing the relationships helps to make flexible and correct use of the data when forming queries.
Designing the tables well can make the relationships more obvious and more useful. Using relationships in the data is the primary power behind using relational databases in the first place.
About impact on performance: In my experience with MS Access 2003, if you have a multi-user application and use Relationships to enforce a lot of referential integrity, you can take a big hit in terms of response time for the end-user.
There are different ways to take care of enforcing referential integrity. I decided to take out some rules in Relationships, build more enforcement into the front-end and live with some loss of RI. Of course in the multi-user environment, you want to be very careful with that bit of liberty.
In my experience building performance-sensitive databases, Foreign Keys hurt performance pretty significantly, since they have to be checked every time the referring record is inserted/updated or master record is deleted. If you need a proof, just look at the execution plan.
I still keep them for documentation and for tools to use but I usually disable them, especially in high-performance systems where access to DB is only through the application layer.