Recommendations for table structure in MySQL - mysql

Hi I've got a small internal project I am working on. Currently it only serves my company, but I'd like to scale it so that it could serve multiple companies. The tables I have at the moment are USERS and PROJECTS. I want to start storing company specific information and relate it to the USERS table. For each user, I will have a new column that is the company they belong to.
Now I also need to store that companies templates in the database. The templates are stored as strings like this:
"divider","events","freeform" etc.
Initially I was thinking each word should go in as a separate row, but as I write this I'm thinking perhaps I should store all templates in one entry separated by commas (as written above).
Bottom line, I'm new to database design and I have no idea how to best set this up. How many tables, what columns etc. For right now, my table structure looks like this:
PROJECTS
Project Number | Title | exacttarget_id | Author | Body | Date
USERS
Name | Email | Date Created | Password
Thanks in advance for any insights you can offer.

What I would do is create 2 tables:
I would create one table for the different companies, lets call it COMPANY:
Company_id | Title | Logo | (Whatever other data you want)
I would also create one table for the settings listed above, lets call it COMPANY_SETTINGS:
Company_id | Key | Value
This gives you the flexibility in the future to add additional settings without compromising your existing code. A simple query gets all the settings, regardless of how many your current version uses.
SELECT Key, Value FROM COMPANY_SETTINGS WHERE Company_id = :companyId
Te results can then be put into an associative array for easy use throughout the project.

Related

The best solution for designing a automation database? [duplicate]

This question already has answers here:
Native JSON support in MYSQL 5.7 : what are the pros and cons of JSON data type in MYSQL?
(5 answers)
json column vs multiple columns
(4 answers)
Closed 4 years ago.
What is the best way to implement information with a one to many relationship in a large automation system located on a local server?
Getting a report and record it is the most important point of the system.
For example, consider a travel agency that has several guides that perform one tour in week. To record the agency's information, best way is use three tables, one to store the agency's information and one to store personalized guide information and one to store relationship(one to many) but whit this way, changing the person's guide information that will perform a tour this week will change, so the report received from the system will also change. Another method of storing is to use a table, in which the agency's information is stored, and the person's information is also stored in a column in the json format.For example, consider the following table.
Agency Table:
agency_id | name | phone_number | address | guides_details (That information stored in this column is stored in json format like name, mobile and ....)
Now my question is:
Given the fact that the storage size for the project is not important (due to the use on the local server), is the second method suitable for large-scale information storage (archive)? Or, if there's another way to archive it, teach me please.
Generally, its a bad practice to store JSON data in a table if it can be expressed in a tabular format. The reason for this is because you would not be able to query those details in your database language with ease.
I would suggest the following tables:
Agency Table
agency_id | (any other static information)
Agency Details Table
agency_detail_id | agency_id | created_date | name | phone_number | address | (any other changeable details)
Guide Table
guide_id | (any other static information)
Guide Details Table
guide_detail_id | guide_id | created_date | phone | email | (any other changeable details)
Tour Table
tour_id | name | date | agency_detail_id | guide_detail_id
Reasoning:
The details table for agency and guide will allow you to keep different versions of each agency and guide for different tours and will allow you to preserve the ability to link the records back to which agency or guide the tour belongs to even if the details are different.
We have broken the guide details up into a table so that it can easily be queried against.

MySQL Database Design with tags across multiple tables

I am working on some web apps which should all use the same user table. The different applications all need different table designs, so I created one table for each app, with the UserID being a foreign key referring to the user table.
Now I want to add tags to all apps. The tags should be in one table for every app in order to easily query all tags from one user(for searching purposes, the search should be able to find everything tagged with that tag, no matter the app). Personally, I don't think splitting them up into multiple tables would be a good idea, but I am not that into database design so I might be wrong. My current attempt looks something like this:
[tags]
EntryID | UserID | Tag
The thing is that the EntryIDs of course would have to be unique across all app tables with this solution. For the notes app I need something like this:
[notes]
EntryID | UserID | title | content | etc.
For my calendar I have the following table:
[calendar]
EntryID | UserID | name | start | end | etc.
Now I don't know how to manage those EntryIDs. Should I create another table like this
[entries]
EntryID | UserID | type
with type being something like "note" or "calendar", and EntryID being the primary key? And should the type be something like an integer, or a string, or is there a possibility to kind of refer to another table in the type column? And should I then make the EntryIDs in the app tables into foreign keys referring to the entries table?
I put the userID in every table because I think this is going to speed up querying, for example when I need every tag one user has set across all apps. I know normalization usually prohibits this, but I again think that it would very much increase query speed and reduce load for both the MySQL server and my back-end.
I would appreciate every tip for structuring this, and thanks in advance!
You can use inheritance, similar to this:
I'm not sure what the role of the user is supposed to be here, exactly. In the model above, user "owns" an entry and (presumably) tags it. If you want multiple users to (be able to) tag the same entry, USER would need to be connected to the junctions table TAG_ENTITY.
For more on how to physically implement inheritance, see here.
You may also be interested in this and this.

Need help designing ERD for food bank

This is my first project outside of school so I'm rusty and lacking practice.
I want to create a database but I'm not sure if I'm doing ok so far. I need a little help with the reports table.
The situation:
The food bank has multiple agencies who hand out food
Each agency has to submit a report with how many families/people served from a long list of zip codes.
I thought of putting a fk on Report to Zips table. But will that make selecting multiple zips impossible?
Maybe I'm way off base. Does someone have a suggestion for me?
A better name for this table might be FoodService or something. I imagine the kind of reports you really want to end up are not just a single row in this table, so naming it Report is a bit confusing.
In any case, each Report is the unique combination of {Agency ID, ZIP code, Date} and of course Agency ID is a foreign key. The other columns in this table would be number of families and people served, as you've indicated. This means you'll have rows for each agency-ZIP-date combination like this:
Agency | ZIP | Date | FamiliesServed | PeopleServed
Agency A | 12345 | Jan-12 | 100 | 245
Agency A | 12340 | Jan-12 | 20 | 31
Agency B | 12345 | Jan-12 | 80 | 178
Agency B | 12340 | Jan-12 | 0 | 0
Are these totals also broken down by "program"? If so, program needs to be part of the primary key for this table. Otherwise, program doesn't belong here.
Finally, unless you're going to start storing data about the ZIP codes themselves, you don't need a table for ZIP codes.
Usually having orphan tables like "Food" is a sign something's missing. If there's that much data involved, you'd think it would link in to the order model in some capacity, or at the very least you'd have some kind of indication as to which agency stocks which kind of food.
What's curiously absent is how data like "families-served" is computed from this schema. There doesn't seem to be a source for this information, not even a "family served" record, or a spot for daily or weekly summaries to be put in and totalled.
A "Zips" table is only relevant if there is additional data that might be linked in by zip code. If you have a lat/long database or demographic data this would make sense. Having an actual foreign key is somewhat heavy handed, though. What if you don't know the zip? What if, for whatever reason, the zip is outside of the USA? How will you handle five and nine digit zip codes?
Since zips are not created by the user, the zips table is mostly auxiliary information that may or may not be referenced. This is a good candidate for an isolated "reference" table.
Remember that the structure of a diagram like this is largely influenced by the front-end of the application. If users are adding orders for food items, that translates into relationships between all three things. If agencies are producing reports based on daily activity logs, then once again you need relationships between those three entities.
The front end is usually based on use-cases, so be sure you're accommodating all of those that are relevant.

Database Schema allowing for multiple login opportunities (Facebook-Connect, Oauth, OpenID, etc.) for the same account

I want to accomplish nearly the same thing as this question, which is to store authentication data from multiple sources (Facebook, Twitter, LinkedIn, openID, my own site, etc.) so that one person can log in to their account from any/all of the mentioned providers.
The only caveat being that all user data needs to be stored in a single table.
Any suggestions?
If there is no clean way to accomplish this, is it better to have tons of columns for all of the possibly login methods or create additional tables to handle the login methods with Foreign Keys relating back to the user table (as described in this answer)?
perhaps you want to create a table dedicated to the account types, along with a table for the actual user.
Say you have a users table with an auto_increment uinique ID for each user. Then, you want to create another table example: user_accounts, with it's own auto_icnrement ID, another column for relational ID (to the users table and a 3rd (or/and) 4th table for account type / extra data for authentication if needed.
You then insert a record for each account type for each user. Basically it may look like this:
user_accounts
| ID | User_ID | account_type | authentication
| 1 | 1 | facebook | iamthecoolestfacebookerever
| 2 | 1 | google | mygoogleaccount
In it's most simplistic form. you will probably be storing much different data than that, but hopefully you get the point.

Database schema suggestion for widget driven site

I am currently working on restructuring my site's database. As the schema I have now is not one of the best, I thought it would be useful to hear some suggestions from you.
To start off, my site actually consists of widgets. For each widget I need a table for settings (where each instance of the widget has its user defined settings), a table for common (shared items between instances of the same widget) and userdata (users' saved data within an instance of a widget).
Until now, I had the following schema, consisting of 2 databases:
the first database, where I had all site-maintenance tables (e.g. users, widgets installed, logs, notifications, messages etc.) PLUS a table where I joined each widget instance to each user that instanciated it, having assigned a unique ID (so, I have the following columns: user_id, widget_id and unique_id).
the second database, where I kept all widget-related data. That means, for each widget (unique by its widget_id) I had three tables: [widget_id]_settings, [widget_id]_common and [widget_id]_userdata. In each of these tables, each row held that unique_id of the users' widget. Actually here was all the users' data stored within a widget.
To give a short example of how my databases worked:
First database:
In the users table I have user_id = 1
In the widgets table I have widget_id = 1
In the users_widgets table I have user_id = 1, widget_id = 1, unique_id = 1
Second database:
In the 1_settings I have unique_id = 1, ..., where ... represents the user's widget settings
In the 1_common I have several rows which represent shared data between instances of the same widget (so, no user specific data here)
In the 1_userdata I have unique_id = 1, ..., where ... represents the user's widget data. An important notice here is that this table may contain several rows with the same unique_id (e.g. For a tasks widget, a user can have several tasks for a widget instance)
Hope you understood in the rough my database schema.
Now, I want to develop a 'cleaner' schema, so it won't be necessary to have 2 databases and switch each time from one to another in my application. It would be also great if I found a way NOT to dinamically generate tables in the second database (1_settings, 2_settings, ... , n_settings).
I will greatly appreciate any effort in suggesting any better way of achieving this. Thank you very much in advance!
EDIT:
Shall I have databases like MongoDB or CouchDB in my mind when restructurating my databases? I mean, for the second database, where it would be better if I didn't have a fixed schema.
Also, how would traditional SQL's and NoSQL's get along on the same site?
A possible schema for the users_widgets table could be:
id | user_id | widget_id
You don't need the unique_id field in the users_widgets table, unless you want to hide the primary key for some reason. In fact, I would rename this table to something a little more memorable like widget_instances, and use widget_instance_id in the remaining tables of the second database.
One way to handle the second set of tables is by using a metadata style:
widget_instance_settings
id | widget_instance_id | key | value
This would include the userdata, because user_id is related to the widget_instance_id, unless you want to allow a user to create multiple instances of the same widget, and have the same data across all instances for some reason.
widget_common_settings
id | widget_id | key | value
This type of schema can be seen in packages like Elgg.
Do you know the settings a widget class and widget instance could have? In this case these settings could be made columns of the widget_class table (for common settings) and widget_instance (for instance specific settings).
If you don't know them, then you could have a widget_class_settings table that has a many to one relation with the widget_class table and a widget_instance_settings that has a many to one relation to the widget_instance table. Between the widget_instance and the widget_class you could, again, have a many to one relation. The widget_instance could also have a foreign key in the users table, so that you know which user created a specific widget.