MySQL - Database with multiple schemas where table and column names are different - php

Is there a way to have one database that can be represented with different table and column names?
I'm creating a large refactoring of an API, where it only makes sense to rename quite some table and column names in the MySQL database, but the old version of the API still needs to read and write to the existing database. The data is largely the same and the versions can easily co-exist. There is no chance to have two databases running in parallel.
The new API domain layer is fully separated from the persistance layer, but in the persistance layer, I would like to create it properly using new table and column names, instead of having to convert the names for each query.
Is there a way to represent the database structure in multiple ways - effectively making the naming variable? Can you suggest me a solution?
Is there e.g. a way to solve this by replacing a database schema?
I would like the two versions of the API to read and write to database where tables can exist with this (below) difference in naming - but the table and data is the same.
+----------------------------+ +-------------------------+
| old_items | | new_items |
+----+----------+------------+ +----+----------+---------+
| id | meta_key | meta_value | | id | item_key | item_id |
+----+----------+------------+ +----+----------+---------+
The application is written in PHP.
Thanks.

Why you want to rename the column, when you can use alias when getting the column name. like
select metavalue as itemvalue from tablename
Or
Alternatively you can create two seperate tables for each your entity. That makes sense.

Related

Create a lookup table with Doctrine2

I have recently installed Doctrine2 on my web server and all works great. I have setup all my entities but now I'm at the point where I want to create a lookup table and I'm a bit confused how to do that. I want a table which looks like this:
tbl_Role tbl_User
+--------+----------+ +--------+----------+--------------+----------+
| id | Name | | id | Name | Password | Role |
+--------+----------+ +--------+----------+--------------+----------+
| 1 | Admin |
| 2 | User |
| 3 | Free |
+--------+----------+
Between the Role and the User table consists a OneToMany relation (one Role has many Users) and this table does not change in future. I do not want to use Enums because of the update or reorder problem with them (if nevertheless something changed)
My question now is how I can represent this lookup table as a Doctrine entity? Normally if I want to create a new User I have to get the fitting Role from the DB and set it as a reference in the User entity. This seems a bit expensive to me. It would be great if I could have only the Role IDs in static PHP fields so I can set them as reference for the User. Is this possible?
Another problem is how I get the lookup values into the database. Can I implement a method into the Role entity itself which is executed after the Role table is created? This way it would be possible to mark the constructor as private and all values are present after a migration.
First of all, it won't be too expensive, because Doctrine2 has a few cache layers and these queries will be efficiently cached since the Role table won't change.
Anyway, if Role table won't change, I'm not sure if it should be kept in database. You could create a "static" factory service for it to create simple value objects as a part of your domain layer.

MySQL & jQuery: Store dynamic generated content in database

I have a dynamic form that creates some inputs that will generate values and should be saved into the database. Each set of values should be saved separetely in a single field in the database called "Education":
Should be stored like this:
+--------+---------+----------+--------+--------+--------+--------+-----+
| id | name | Education |
+--------+---------+----------+--------+--------+--------+--------+-----+
| 100 | John | [Harvard, Marketing,2009,2014] [MIT,CS,2005,2009] |
+--------+---------+----------+--------+--------+--------+--------+-----+
| 101 | Daniel | [TEC, Marketing,2009,2014] [Standford,CS,2001,2005]|
+--------+---------+----------+--------+--------+--------+--------+-----+
The Education field can have up to 10 sets of values, I'm just showing 2.
Please look at the JSFIDDLE to see how it actually works: http://jsfiddle.net/YueX2/6/
How can I store into the database when a single set of values is edited and saving it into the database only updating the given set of values?
Also, is this the best way to do it?
There is a practice in designing databases called normalization which would lead you to the best way to go about it. Based on your Question and jsFiddle you would end up with 2 separate database tables.
Ex: tbl_Users: which would contain fields such as
userID
userName
Then you would have another table Ex: tbl_Education which would contain a few fields such as
record_id
userID
schoolName
It is in this table where you would set the particular users id in the userID field which would have to match the userID field from tbl_Users and then a single school they attended in the schoolName field. If they attended multiple schools, they would have multiple entries in the tbl_Education table but only a single entry in the tbl_Users table. If you need to retrieve the data you would perform a SQL query on the two table and join on the User_id field. This would result in multiple records being returned, but with all of the data needed.
Any information which is specific to the particular part of their education would go in the tbl_Education table and anything specific to the user (hair color, eye color, height, etc) would go in the tbl_Users table.
Ex SQL Query:
SELECT tbl_Users.userID, tbl_Users.userName, tbl_Education.schoolName
FROM tbl_Users, tbl_Education
WHERE tbl_Users.userID = tbl_Education.userID;
The WHERE clause is essentially the join between the two tables. There are many ways to write this query, I used the method which seems visually the easiest to see what is going on.
Here is the wikipedia link for normalization to get you started.
http://en.wikipedia.org/wiki/Database_normalization
This is not the best way to solve this problem. You better make 2 tables.
Table users:
+--------+---------+
| id | name |
+--------+---------+
Table education:
+--------+----------+------------+-------+-----+------+
| id | location | discipline | start | end | user |
+--------+----------+------------+-------+-----+------+
As education.user you save a foreign key users.id from the user table. the implementation of the input form is on the one hand side more complex but you have no limitations of entrys per user nor too much overhead in your database.

CakePHP Normalization

I am debating over the amount of normalization to use in my tables.
For example, if I have a database table called players with columns such as name, hometown, etc...
Other columns are options bats (right, left, or switch), or status (active, injured) that with be displayed as radio buttons or drop downs.
Currently, our database stores these options in their own tables bats and statuses and we reference the related table with the fields bat_idand status_id.
If the bats and statuses tables are simply storing a list of names and ids and will always have less than 10 values, should I flatten the database and simply store the values directly in the players table?
When creating radio inputs for those fields I might have to execute a group by query on a large table. Would it make sense to store the possible values globally as an array in app/config/bootstrap.php or by using the configure class?
For my opinion you can really seldom overuse normalization. I'd avoid globals as much as I can.
If your bats and statuses tables will hold "only" configuration or status key data you might put all of them together in a single table, accessible by namespace.
E.g.:
id | namespace | value
---------------------------
1 | bats | left
2 | bats | right
3 | bats | swing
4 | status | active
5 | status | injured
... etc, you get it. Simply have an index on the namespace to help the database - unless there are really only a few lines in there where a decent DB would ignore the index anyway.

Which approach is best for storing a list of words in mysql that will later be used for statistics?

DETAILS
I have a quiz (let’s call it quiz1). Quiz1 uses the same wordlist each time it is generated.
If the user needs to, they can skip words to complete the quiz. I’d like to store those skipped words in mysql and then later perform statistics on them.
At first I was going to store the missed words in one column as a string. Each word would be separated by a comma.
|testid | missedwords | score | userid |
*************************************************************************
| quiz1 | wordlist,missed,skipped,words | 59 | 1 |
| quiz2 | different,quiz,list | 65 | 1 |
The problem with this approach is that I want to show statistics at the end of each quiz about which words were most frequently missed by users who took quiz1.
I’m assuming that storing missed words in one column as above is inefficient for this purpose as I'd need to extract the information and then tally it -(probably tally using php- unless I stored that tallied data in a separate table).
I then thought perhaps I need to create a separate table for the missed words
The advantage of the below table is that it should be easy to tally the words from the table below.
|Instance| missed word |
*****************************
| 1 | wordlist |
| 1 | missed |
| 1 | skipped |
Another approach
I could create a table with tallys and update it each time quiz1 was taken.
Testid | wordlist| missed| skipped| otherword|
**************************************************
Quiz1 | 1 | 1| 1| 0 |
The problem with this approach is that I would need a different table for each quiz, because each quiz will use different words. Also information is lost because only the tally is kept not the related data such which user missed which words.
Question
Which approach would you use? Why? Alternative approaches to this task are welcome. If you see any flaws in my logic please feel free to point them out.
EDIT
Users will be able to retake the quiz as many times as they like. Their information will not be updated, instead a new instance would be created for each quiz they retook.
The best way to do this is to have the word collection completely normalized. This way, analyses will be easy and fast.
quiz_words with wordID, word
quiz_skipped_words with quizID, userID, wordID
To get all the skipped words of a user:
SELECT wordID, word
FROM quiz_words
JOIN quiz_skipped_words USING (wordID)
WHERE userID = ?;
You could add a group by clause to have group counts of the same word.
To get the count of a specific word:
SELECT COUNT(*)
FROM quiz_words
WHERE word LIKE '?';
According to database normalization theory, second approach is better, because ideally one relational table cell should store only one value, which is atomic and unsplitable. Each word is an entity instance.
Also, I might suggest to not create Quiz-Word tables, but reserve another column in Missed-Word table for quiz, for which this word was specified, then use this column as a foreign key for Quiz table. Then you probably may avoid real time table generation (which is a "bad practice" in database design).
why not have a quiz table and quiz_words table, the quiz_words table would store id,quizID,word as columns. Then for each quiz instance create records in the quiz_words table for each word the user did use.
You could then run mysql counts on the quiz_words table based on quizID and or quiz type
The best solution (from my pov) for what are you trying to achieve is the normalized aproach:
test table which has test_id column and other columns
missed_words table which has id (AI PK) and word (UQ) , here you can also have a hits column that should be incremented each time that a association to this word is made in test_missed_words table this way you have the stats that you want already compiled and you don't need them to be calculated from a select query
test_missed_words which is a link table that has test_id and missed_word_id (composite PK)
This way you do not have redundant data (missed words) and you can extract easily that stats that you want
Keeping as much information as possible (and being able to compile user-specific stats later as well as overall stats now) I would create a table structure similar to:
Stats
quizId | userId | type| wordId|
******************************************
1 | 1 | missed| 4|
1 | 1 | skipped| 7|
Where type can either be an int defining the different types of actions, or a string representation - depending on if you believe it can ever be more. ^^
Then:
Quizzes
quizId | quizName|
********************
1| Quiz 1|
With the word list made for each quiz like:
WordList (pk: wordId)
quizId | wordId| word|
***************************
1 | 1 | Cat|
1 | 2 | Dog|
You would have your user table however you want, we are just linking the id from it in to this system.
With this, all id fields will be non-unique keys in the stats table. When a user skips or misses a word, you would add the id of that word to the stats table along with relevant quizId and type. Getting stats this way would make it easy as a per-user basis, a per-word basis, or a per-type basis - or a combination of the three. It will also make the word list for each quiz easily available as well for making the quizzes. ^^
Hope this helps!

Using RDBMS for Users and Link with NoSQL Items

I am planning an application and wish to maintain a relational database and other non-relational, respectively, MySQL and MongoDB.
One fact is that in relational database are maintained users, and non-relational, is maintained by this user generated content, where involves geo queries.
The problem now is how to *create a link between user and your item*s using both databases and maintaining the performance or am adopting the wrong approach?
My idea is to create a product table with a foreign key to the user in mysql and objectId of the product in the database non-relational.
Example MySQL Table:
table: products_relationship
| account_id | product_objectid |
| ---------- | -------------------------------- |
| 1 | 0b694fc34c9663883a5d4b32371f8333 |
| 1 | 0b694fc34c9663883a5d4b32371f9837 |
| 2 | 0b694fc34c9663883a5d4b32371f9bfc |
| 5 | 0b694fc34c9663883a5d4b32371fcb5f |
| 1 | 0b694fc34c9663883a5d4b32371fd809 |
So, the user at account_id = 1 has a first name, email and other data. And owns 3 products.
Should I adopt a new methodology? I'll be gaining performance with that? Am I losing the functionality of NoSQL with that?
I work on a system at work that does just this. We have relational databases and NoSQL databases and we use a product called Mule (http://www.mulesoft.org/) to integrate them.
I would strongly recommend picking either MySQL or Mongo and doing all your PHP work against one of those databases. You can move data in near real time from MySQL->Mongo or from Mongo->MySQL. Mule is good at that.
You aren't going to be able to efficiently do "joins" across systems.
Mule will also help you do transformations on the data when you move it. As an example, you can take normalized data in MySQL and denormalize it for storing in Mongo.
I realized that I adopted a complex architecture while I did not need much complexity. There is no reason for me to want my users are in relational databases. Yes they can stay within the MongoDB without any problem, and the products within each user. This is a relationship that I create.
If I want, I can make the connection using _objectId

Categories