How to best normalize a personnel database, table options given - mysql

I have an application in which I register a user using only their email and password. Then later on, they fill in their profile, which includes their personal information such as numbers, address, the hours they work during the week, etc.
I'm confused now whether to store all that data in the same table or to have the following:
users (for authentication), persons (for the profile), address (for um, addresses), numbers (you get the gist).
I would like to know a DBA's input on this. How would you design this database for a userbase of 500 people, give or take. Are there going to be problems in the long run if I keep all the fields - around 30 right now - in the same table?

It is a good idea to separate site-used data from invoicing data.
When you are displaying a homepage after your user logs in, you usually want to display username and avatar. Also, you use email and other account info to log in. That is probably some stuff you want to keep handy all the time. Move it into one table then.
Addresses (invoice, delivery, etc.) and phone numbers are usually stored separately, as you only need those when placing an order.
Rule of thumb: keep column count under 30, read as few tables as possible. Of course you should design properly (never mix entities, etc.), but this rule is a simple check that you are not creating something awful.

Related

Creating the right Database table structure for address change + pricing

I'm a little stumped on whether i can make this process of changing addresses easier. I'll explain the situation:
Basically I have three entities, Students, Addresses, StudentsAddresses. Students have many addresses, since they can change alot and rapidly (especially foster kids / homeless kids). So ill be changing them a lot. However based on each address I Want a user to attach (enter it via the UI) the price it would cost to pick that student up via bus service. So my initial thought was, ok, let me attach a column onto my join table 'StudentsAddresses' called 'dailyPrice', this is the cost for each day a student is picked up, and another column called 'adjustmentPrice', which is an additional cost for whatever special circumstance that requires extra work to pick up a student. Is my thinking going to cause me problems the more students I have in the future? Will it get harder to manage?
Another option I thought about, was creating a new Table called Pricing. And another join-type table called StudentsAddressesPricing
StudentsAddressPricing has three columns,
studentId
addressId
pricingId
each field connects the three together. So if i ever needed Students, with their addresses, and the pricing, i would query this table and eager load Students, Addresses, and Pricing. Does this approach seem much cleaner since i've abstracted pricing out a bit? Trying to determine the best way to go about this without having to many headaches in the future incase I wan't to add more attributes pricing related, or address related.
And then I even thought, hey what if pricing is just different for one day? How would I even consider that. Would I need a different kind of entity to handle that? Is doing alot of joins going to hurt my application performance?
Just looking for some insight on how others would do it, and criticism on why im off the ball.
The main question you should ask yourself is: on what does the price depend?
If the price is determined by the address, you might as well add it to addresses. If the price also depends on the student (e.g., depending on their financial situation), it would make sense to put it into studentsaddresses.
In other words: The table where the price is stored should have foreign keys to everything outside the table that determines the price. If that makes it fit into one of the existing tables, keep it there.

Database design for weekly time tracking

I am planning on creating a database to track user's time in/time out M-F. Every week should begin on monday and run through sunday.
I have a table filled with my entire user population, so I know which users I need to create entries for and where they belong to. I have proposed so far, a table consisting of the following fields to track the entries (along with example data to fill the fields):
Field Name in table (Example of possible data)
---------------------
Employee (John Smith) 'String
Unit (Quality Assurance) 'String
WeekOf (9/9/13) 'date
InMonday (6:30) 'string, validate either a time in/out or N/A if holiday/vacation
OutMonday (3:15) '^^
HoursWorkedMonday (8.00) 'total hours worked
VacationMonday (0.00) 'if N/A for time, should have hours here
OvertimeMonday (0.00) 'any additional work hours should go here
For this instance, I would have to create In/Out for each day of the week (and perhaps track the date that each day is for). Is this extraneous or is there a seemingly better organization to tracking weekly time measurements? Should I use one table with a unit indicator or multiple tables for each unit?
Usually it's one table with a Date field, an In field and an Out field. That's pretty much standard timesheet data. Take a look at how this guy has it set up.
Make sure you're using an Employee ID in the timesheet, and then you would have a corresponding Employee table with all relevant info (ID, Name, Address, whatever else you store on him/her).
While this project is technically feasible, I have to question the value of making it yourself in Access.
The main issue is with security:
As a desktop program, this can be very easy to hack without precautions. Keep in mind that with Access, the user interface and the designer interface are by default the same thing.
If this is going to be a simple, straightforward db, a motivated user just needs to open the navigation panel and they can add/edit/delete all the timesheets.
If you hide the navigation panel, the user can just do a quick google search and learn to hit F11 (or find it by accident, either way)
You can try regularly (daily? hourly?) transferring the data from the publicly accessible back-end to an archive db that is not accessible to the general users. This can work, but still gives them a window to edit records. And if you don't do the transfer right, they can still add old records.
As a webform on a SharePoint, this can be fairly secure. I'd recommend this if you have Sharepoint.
You should also consider your development time. This is a very common business task across many industries, from restaurants to factories to schools. As such, there's a huge number of cheap web-based options already out there that you can start using today. I'll even assume some of these include summary reviews breaking out numbers by departments as well.
I've never researched these myself, but a quick google search found this interesting page: http://en.wikipedia.org/wiki/Comparison_of_time_tracking_software

Database user table design, for specific scenario

I know this question has been asked and answered many times, and I've spent a decent amount of time reading through the following questions:
Database table structure for user settings
How to handle a few dozen flags in a database
Storing flags in a DB
How many database table columns are too many?
How many columns is too many columns?
The problem is that there seem to be a somewhat even distribution of supporters for a few classes of solutions:
Stick user settings in a single table as long as it's normalized
Split it into two tables that are 1 to 1, for example "users" and "user_settings"
Generalize it with some sort of key-value system
Stick setting flags in bitfield or other serialized form
So at the risk of asking a duplicate question, I'd like to describe my specific scenario, and hopefully get a more specific answer.
Currently my site has a single user table in mysql, with around 10-15 columns(id, name, email, password...)
I'd like to add a set of per-user settings for whether to send email alerts for different types of events (notify_if_user_follows_me, notify_if_user_messages_me, notify_when_friend_posts_new_stuff...)
I anticipate that in the future I'd be infrequently adding one off per-user settings which are mostly 1 to 1 with users.
I'm leaning towards creating a second user_settings table and stick "non-essential" information such as email notification settings there, for the sake of keeping the main user table more readable, but is very curious to hear what expects have to say.
Seems that your dilemma is to vertically partition the user table or not. You may want to read this SO Q/A too.
i'm gonna cast my vote for adding two tables... (some sota key-value system)
it is preferable (to me) to add data instead of columns... so,
add a new table that links users to settings, then add a table for the settings...
these things: notify_if_user_follows_me, notify_if_user_messages_me, notify_when_friend_posts_new_stuff. would then become row insertions with an id, and you can reference them at any time and extend them as needed without changing the schema.

database modelling -mysql

I am doing the design of a database, that will have eventually thousands of users. Each user has your profile and specific data associated.
In your opinion, it is best practice a table for id, username, activationLink and hash and another for address, age, photo, job, or it is best a unique table for all stuff?
thanks for your time
If:
All (or almost all) users have all data filled
Most of the time you query for all fields
then keep them in a single table, otherwies split them.
In your model, activationLink seems to be queried for only once per activation, so I'd move it into a separate table (which would allow deleting it after the account had been activated).
Address, age, photo and job are usually shown along with the username, so it would be better to merge them into a single table.
Don't allow your initial design to limit the ability (or just make it difficult) to expand your requirements in the future.
At the moment, a user may have one address so you might put it in the users table - what if you want them to be able to store "work" and "home" addresses in future, or a history of past addresses?
A user may only be allowed to have a single photo, but if you put it (or a URL for it) in users.photo, then you'd have to change your data structure to allow a user to have a history of profile photos
As Quassnoi mentions, there are performance implications for each of these decisions - more tables means more complexity, and more potential for slow queries. Don't create new tables for the sake of it, but consider your data model carefully as it quickly becomes very hard to change it.
Any values that are a strict 1-to-1 relationship with a user entity, and are unlikely to ever change and require a history for (date of birth is a good example) should go in the table with the core definition. Any potential 1-to-many relationships (even if they aren't right now) are good candidates for their own tables.

Shall I put contact information in a separate table?

I'm planning a database who has a couple of tables who contain plenty of address information, city, zip code, email address, phone #, fax #, and so on (about 11 columns worth of it), a table is an organizations table containing (up to) 2 addresses (legal contacts and contacts they should actually be used), plus every user has the same information tied to him.
We are going to have to run some geolocation stuff on those addresses too (like every address that's within X Kilometers from another address).
I have a bunch of options, each with its own problem:
I could put all the information inside every table but that would make for tables with a very large amount of columns which I'd have problems indexing, and if I change my address format it'll take a while to fix it.
I could put all the information inside an array and serialize it, then store the serialized information in one field, same problem with the previous method with a little less columns and much less availability through mysql queries
I could create a separate table with address information and link it to the other tables either by
putting an address_id column in the users and organizations table
putting a related_id and related_table columns in the addresses table
That should keep stuff tidier, but it might create some unforeseen problems with excessive joining or whatever.
Personally I think that solution 3.2 is the best, but I'm not too confident about it, so I'm asking for opinions.
Option 2 is definitely out as it would put the filtering logic into your codes instead of letting the DBMS handle them.
Option 1 or 3 will depend on your need.
if you need fast access to all the data, and you usually access both addresses along with the organization information, then you might consider option 1. But this will make it difficult to query out (i.e. slow) if the table get too big in mysql.
option 3 is good provided you index the tables correctly.