Can i manage employee related data in one table? - c#

I have seen people using ‘DataListValue’ table for storing those values (Call_Types, DepartmentCodes, Divisions and etc) which are used quite often in the drop down list on UI.
This way i can manage them in one table and will have one screen to update codes.
I am wondering if it is okay to keep DepartmentCode,RoleCode,CountryCode in the Data_List Table? Or I should have them in separate table?

It is common practice to have a single codes table that stores code/description pairs with some kind of table type column. For instance, you might commonly see a table like this:
CodesTable
TableId
Code
Description
However, I have never thought it was a good idea. Even if all you store is a code and a description, it's better to make a new table for each set of codes. That way your foreign key relationships will be more clear. Plus, inevitably, you will one day need to store some additional data about one of those code sets and you'll end up needing to add an additional column that only applies to one of the code sets that are stored in the table and the column will be null for all the other rows. It always turns ugly fast.
For instance, lets say, as in the example above, you set TableId to "C" for all the Country codes and you set it to "D" for all Department codes. But then next month a new requirement comes in that requires you to store a postal abbreviation for each Country code. Do you add a PostalAbbreviation column to the table even though it will never apply to Department codes? Or do you create another table that just stores additional data for each country code? How do you know what "C" and "D" mean unless you have some other place to look them up? All around it's just a bad idea.

Related

Implementing array like structure in MySQL database

I'm currently trying to implement a table within my SQL database. I'm looking to create a table that can be used to check if a user on my website has liked a post. The idea is to have a table with one axes iterating the posts on the website and one axis with the userID values iterated. Then in each box hold a binary value as to whether they have liked it. I'm just wondering how I would implement this. I have been doing this in C# by creating classes and converting these into server side code using Entity Framework 6.4.0.
Any help would be great.
What you are suggesting is a normalized structure for your use case; it would, for example, require adding more columns to the table everytime a post is added to the database (or a user, depending on whether you use rows or columns).
A typical database solution would be a bridge table, that represents the many to many relationship between posts and users.
Say table user_like_posts, with the following columns:
user_id -- foreign key to the "users" table
post_id -- foreign key to the "posts" table
You may want to add additional columns to the bridge table, like the timestamp when the user liked the post, or the-like.
Will every user have an opinion on every post? If not then you don't have the data you described. If users and posts are not related one to one then you have a simple relation. For each post that a user likes (or dislikes?) there is an entry for that user:
Likes/Dislikes Table:
User identifier
Post identifier
The binary value that indicates like or dislike
If the table only indicates 'likes' then you don't need the last column.
A design like this would work even if every user and every post is in this table. The table might get large in a hurry and keep growing every time you introduced a new post. But if this table only includes actual 'likes' (and/or 'dislikes') it should be manageable.
For a class you just have an enumerable that has the posts 'liked' (and possibly another that indicates the posts 'disliked.')
Think about what you are trying to represent. Ask yourself questions. Don't just latch on to an idea and try to 'do' it.
Will every user have an opinion of every post?
Do you need to store both 'likes' and 'dislikes?'
Can there be a 'neutral' opinion on a post?
Can users change their opinions?
You can only discover the correct data structure by asking and answering all the questions that matter to your situation (my list is not exhaustive - it is only an example.)

Table design for SQL

i hope you can help me out here - i have a question about designing a SQL table. I know how to write to a database and perform queries using C#, but i have never really had to design one. So i thought i would give it a shot just our of interest.
Lets assume i have a table named family_surname. Within that table, there could be x amount of family_members, say ranging from 2 people to 22 people. How can i reference family_members against family_surname?
So i would have
FAMILY SURNAME
Smith,
Jones,
Brown,
Taylor,
etc.
And then Smith may have 5 members, to where i would like to record age, height, weight, whatever. Jones may have 8 members - it could vary between families.
I dont really want 'surname' listed 8 times for each member - ideally the surname row would reference (or somehow point to) a corresponding row in another table. And thats where im having trouble!
I hope i make sense; like i say, im just interested, but i would like to know how to do this with two tables.
Anyway, thank you for your help, i appreciate it.
EDIT
Thank you to everone who commented - certainly some useful information here, which i appreciate. Im reading up and researching some SQL bits and peices, and so far its pretty good.
Thanks again, guys!
What you are asking is a question about normalization. The table would look like:
Create table surname (
SurnameID int,
Surname varchar(255)
)
The other tables would reference the surname by using the I'd. Also, you probably want surnameid to be unique, a primary key, and auto incrementing. Those are more advanced topics.
That said, I'm not sure surname is a great candidate for splitting out like this. One reason to normalize data is to maintain relational integrity. In this case, it means that when you change "Smith" to "Jones", all the Smiths change at once. I don't think this is a concern in your case.
Yes the previous answer about learning about database normalization is probably accurate but for starters....
Breaking down the person's name (first and last) is probably a bit much. Unless you are assuming everyone named "jones" are ALL related. Think of each table as an entity/object and try to connect them to real world "objects" as much as possible. Since a person needs both first and last name (minimum) to uniquely identify them, they should not be normalized in that way.
In the scenario you've painted, you should have a Persons table that has PersonId, FirstName, LastName. And if need be, a separate table to store other information. However, since the person can only be of one height, weight, age, etc... those should be stored in the Persons table.
Therefore, you really only need one table here. Unless you start getting into phone numbers, addresses, etc.
The decomposition can be done as follows
CREATE TABLE SURNAMES(INT ID, SURNAME VARCHAR2(200))
CREATE TABLE DETAILS(INT ID, FOREIGN KEY(SURNAME_ID) REFERENCES SURNAMES(ID), PARAM1, PARAM2 .....)
A rough sketch of the decomposition is
Get the list of attributes (SURNAME, PARAM1, PARAM2,....).
Based on the list of attributes the following keys can be inferred :
1. (SURNAME)
2.(PARAM1,PARAM2...)
A separate table is created for each set of keys
I dont really want 'surname' listed 8 times for each member
Why? Have you measured on realistic amounts of data and determined it's actually a problem?
Unless you plan having additional data specific to the surname (and independent of persons who have that surname), there is nothing wrong about surname not being in its own table. You are not breaking any normal form.
In fact, what you propose can be a really bad idea, for following reasons:
First and foremost, you'd need a JOIN just to find out person's surname - bad for performance.
It complicates (and slows-down) insertion/modification/deletion of persons.
When inserting a new person, you'd have to search the surname table to decide whether you can "reuse" the existing one or insert the new one.
Modification (e.g. when a wife takes husband's surname) is a combination of deletion (see below) and insertion.
Can a surname exist without any person having it? If no, there is no good declarative integrity to enforce this. At best you'd need to write some triggers.
You might not end-up saving much space after all - the additional table will have its own storage overheads (such as the index "underneath" the primary key) which may "eat" much of the anticipated storage saving.

Linq to SQL, Update a lot of Data before One Insert

Before insert new value to table, I need change one field in all rows of that table.
What the best way to do this? in c# code, ore use trigger? if C# can you show me the code?
UPD
*NEW VERSION of Question*
Hello. Before insert new value to table, I need change one field in all rows of that table with specific ID( It is FK to another table).
What the best way to do this? in c# code, ore use trigger? if C# can you show me the code?
You should probably consider changing your design this doesn't sound like it will scale well, i would probably do it with a trigger if it is always required, but if not, id use ExecuteCommand.
var ctx = new MyDataContext();
ctx.ExecuteCommand("UPDATE myTable SET foo = 'bar'");
Looking at your comment on Paul's answer, I feel like I should chime in here. We have a few tables where we need to keep a history of each entry in that table. We implement this by creating a separate table for each. For example, we may have a Comment table, and then a CommentArchive table with a foreign key reference to the CommentId in the Comment table.
A trigger on the Comment table ensures that each time certain fields in the Comment table are updated, the "old" version (which is accessible via the deleted table in the trigger) gets pushed to the CommentArchive table. Obviously, this means several CommentArchive entries may exist for each Comment, but if you're only looking for the "active" comments, you just look in the Comment table. And if you need information about the history of a comment, you can easily use LINQ to SQL to jump from the Comment you're interested in to the CommentArchives that reference it.
Because the triggers we use in the above example only insert a single value into the Archive table for each update, they run very quickly and we get good performance. We had issues recently where I tried making the triggers more complex and we started getting dead-locks with as few as 15 concurrent transactions. So the lesson is that you should make these triggers simple, and make them touch as few rows in as few tables as possible.

Defining Status of data via Enum or a relation table

I have an application which has rows of data in a relation database the table needs a status which will always be either
Not Submitted, Awaiting Approval, Approved, Rejected
Now since these will never change I was trying to decide the best way to implement them I can either think of a Status enum with the values and an int assigned where the int is placed into the status column on the table row.
Or a status table that linked to the table and the user select one of these as the current status.
I can't decide which is the better option as I currently have a enum in place with these values for the approval pages to populate the dropdown etc and setup the sql (as it currently using to bool Approved and submitted for approval but this is dirty for various reasons and needs changed).
Wondering what your thought on this were and whether I should go for one or the other.
If it makes any difference I am using Entity framework.
I would go with the Enum if it never changes since this will be more performant (no join to get the status). Also, it's the simpler solution :).
Now since these will never change...
You can count on this assumption being false, and sooner than you think.
I would use a lookup table. It's far easier to add or change values in a lookup table than to change the definition of an enum.
You can use a natural primary key in the lookup table so you don't need to do a join to get the value. Yes a string takes a bit more space than an integer id, but if your goal is to avoid the join this will accomplish that goal.
I use Enums and use the [Description("asdf")] attribute to bind meaningful sentences or other things that aren't allowed in Enums. Then use the Enum text itself as a value in drop downs and the Description as the visible text.

Saving multiple items per single database cell

i have a countries list. Each user can check multiple countries. Once saved, this "user country list" will be used to get whether other users fit into countries certain user chose.
Question is what would be the most efficient approach to this problem...
I have one, one to save user selection as delimited list like Canada,USA,France ... in single varchar(max) field but problem with it would be that once user from Germany enters page i perform this check on. To search for Germany i would be needed to get all items and un-delimit each field to check against value or to use sql 'like' which again is pretty damn slow..
If you have better solution or some tips i would be glad to hear.
Just to make sure, many users will have their own selections of countries from which and only they want to have users to land on their page. While millions of users will reach those pages. So the faster approach will be the better.
technology, MSSQL and ASP.NET
thanks
You should not store a list of values in one cell. Consider having a separate table that stores each of the selected countries with a foreign key reference to the user table. This is standard Database Normalization.
PLEASE don't go down the route you're thinking of, storing multiple entries in one field. I've had to re-write more applications because of bad database design than for any other reason, and that is a bad design.
Added
I have this poster on my wall at work: http://www.informationqualitysolutions.com/FreeStuff/rettigNormalizationPoster.pdf
One of my predecessors was a newbie to DB Design, and this helped her a lot. I keep it for any new hires that may need it. It explains normalization very nicely, with examples.
Do not save delimited fields into your database. Your database will not be normalized.
You need a many-to-many table for users and countries:
UserId
CountryId
If you do start using a delimited field, you end up needing to parse it (either in SQL or your Code). It is more difficult to query and optimize.
In this case, you want will want to create a table called UserCountries (or some such) which would store the UserID and CountryID. This is a standard relational construct. To beginners, it seems strange and too involved, but this structure makes it very easy and very fast to write flexible queries against this type of data. No delimiting required!
I think it would be better to use a UserCountry table, which contains a link to the User and the Country table. This creates a lot more possibilities to query against the database. Example queries that are much simpler this way:
Number of Countries per user
All users which selected a particular country
Sort all popular countries
Do not store multiple countries in a single field. Add 2 additional tables - Countries (ID, Name) and UserCountries (UserID, CountryID)

Categories