Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
Today I was working on my website and I asked myself a simple question.
Does storing an array with all informations is better than saving those one in different fields?
For example if I store a word, a password and a number in one field on the database in this way
+-------------+----------------------------------------------------------------+
| Field | Value |
+-------------+----------------------------------------------------------------+
| all | ["test","fa26be19de6bff93f70bc2308434e4a440bbad02","25468684888"] |
+-------------+----------------------------------------------------------------+
Is it better than saving it in this way?
+-------------+------------------------------------------+
| Field | Value |
+-------------+------------------------------------------+
| word | test |
| password | fa26be19de6bff93f70bc2308434e4a440bbad02 |
| number | 25468684888 |
+-------------+------------------------------------------+
I think that the first method is faster than the last one because you need only to SELECT one field and not three or more. What do you think about it?
The second method. By far.
You should never put more than one piece of data into a single column.
A single row of data shuld contain all the information you need:
id name password
1 Fluff itsASecret
2 Flupp Ohnoes
Basically, it has to do with updates, selects, searches and pretty much everything that databases do. They are made to do it on single columns, not little bits of data inside a string.
Taking your example, how do you update the password? How do you put an index on the user ID?
What if you also had a bit of data called "NumberOfVotes" If you had it all in one column in a pseudo-array, how do you get a tally of all the votes cast by all users? Would you REALLY want to pull each entry out into PHP, explode it out, add it to the running total and THEN display how many votes have been cast? What if you had a million users?
If you store everything in a ingle column, you could do a tally really easily like this:
select
sum(NumberOfVotes)
from
yourTableName
Edit (Reply to faster query):
Absolutely not, the time it takes to compelte a query will come down to two things:
1) Time it takes to execute the query
2) Time it takes to return all the data.
In this case, the time it takes to return the data will be the same, after all, the database is returning the same amount of bytes. However, with tables that are properly set up, just FINDING the right data will be faster by orders of magnitue.
As an example of how difficult it would be to simply USE a table that has the various bits of information all mumbled together, try to write a query to update the "number" value in the row that starts with the word "test".
Having said that, there are possibly some potential cases where it can in fact be okay to store multiple "fields" of data in one column. I once saw (and copied) an exceptionally interesting permissions system for users that stored the various permissions in binary and each digit in the number equated to being allowed/not being allowed to perform a certain type of action. That was however one interesting example - and is pretty much what I would call an exception that proves the rule :)
I think that the first method is faster
is your main problem actually. You are comparing solutions from only "is it faster" point of view. While you have no measure to tell if there is any difference at all. Or, if even there is, if such a difference does matter at all. So, the only your reason is a false one. While you completely overlook indeed important, essential reasons like proper database design.
Saving in separate fields is a lot more flexible as you are then able to easily search/manipulate data using SQL queries, whereas if they were in an array you would frequently find yourself needing to parse data outside SQL. Consider the following example:
+-------------+----------------------------------------------------------------+
| Field | Value |
+-------------+----------------------------------------------------------------+
| all | ["1","fa26be19de6bff93f70bc2308434e4a440bbad02","25468684888"] |
+-------------+----------------------------------------------------------------+
Using the above table, you need to find the number field for the user with id 1, however there is nothing to search for, you can't simply to a query for the value 1 somewhere in the all field, as that would find every instance of the number 1!
You'll also encounter this problem when changing data in your DB, as you'll have to get the current array, parse it, change the value, then reinsert it.
Also you'll need to put some form of ID as a field to act as a primary key.
However with separate fields for each value, it's fairly simple:
+-------------+------------------------------------------+
| Field | Value |
+-------------+------------------------------------------+
| id | 1 |
| password | fa26be19de6bff93f70bc2308434e4a440bbad02 |
| number | 25468684888 |
+-------------+------------------------------------------+
SELECT `number` FROM mytable WHERE id = 1
The second option is better because its more readable and maintainable.
If someone who didnt write the code has to maintain it, the first option is terrible.
If you ever need to change a field, or add a field, likewise, the first option is a nightmare.
The second option requires much less work.
Keep it simple!
I think given example is trivial and that's why answer for specific example is 2nd method. But there are time's when first method is far more easy to implement. For example you create pages for website dynamically from admin panel, and in start you don't know all the values that will be used in every page. So you put general options like in 2nd method, and put something like page_data and use it to store serialized object. Now you should use serialized object for data that are not likely to change individually, as they are treated as single piece of data.
In your code you fetch serialized object, do unserialize and use them as normal. This way you can add page specific data that are not generalized for every page, but still the page's are the same.
Related
I'm building my first app right now, but I'm new to mysql databases.
I want to store users personalized settings in database, and here are two scenarios to make that happen:
First one:
COLUMNS: "uid" | "app_settings"
ROWS: 1 | 0,1,0,1,ffff00,#ff0000
Which is storing them as an array, and breaking them up by PHP explode.
Second one:
COLUMNS: "uid" | "show_menu" | "show_toolbar" | "show_email | "menu_color" | "toolbar_color"
ROWS: 1 | 0 | 1 | 1 | #ffff00 | #ff0000
Which is storing each in a separate column.
Both ways work fine, but I want to know if it's a bad practice to use the first method.
Does the extra processes to break apart each value is overwhelming for the server resources in a large scale? (Using the PHP explode) or selecting multiple columns is somehow just like exploding them by php in terms of processing speed?
It all depends on what for do you intent to use this data.
Main purpose of using separate columns in database is to have ability to index such data.
If it is a matter of storage only you can use your storage format in one field, but it is much better to use well known format as json (json_encoding in PHP before storing in db, and json_decode after reading).
Also if you really want to save up space, then assuming, that things such as "show_menu" / "show_toolbar" are simply boolean flags, you can store them in one number as a bit fields. For example field named show_rights may have value of 6 which translates to binary 110, so [1: show_menu][1: show_toolbar][0: show_email].
For an MySQL table I am using the InnoDB engine and the structure of my tables looks like this:
Table user
id | username | etc...
----|------------|--------
1 | bruce | ...
2 | clark | ...
3 | tony | ...
Table user-emails
id | person_id | email
----|-------------|---------
1 | 1 | bruce#wayne-ent.com
2 | 1 | ceo#wayne-ent.com
3 | 2 | clark.k#daily-planet.com
To fetch data from the database I've written a tiny framework. E.g. on __construct($id) it checks if there is a person with the given id, if yes it creates the corresponding model and saves only the field id to an array. During runtime, if I need another field from the model it fetches only the value from the database, saves it to the array and returns it. E.g. same with the field emails for that my code accesses the table user-emails and get all the emails for the corresponding user.
For small models this works alright, but now I am working on another project where I have to fetch a lot of data at once for a list and that takes some time. Also I know that many connections to MySQL and many queries are quite stressful for the server, so..
My question now is: Should I fetch all data at once (with left joins etc.) while constructing the model and save the fields as an array or should I use some other method?
Why do people insist on referring to the entities and domain objects as "models".
Unless your entities are extremely large, I would populate the entire entity, when you need it. And, if "email list" is part of that entity, I would populate that too.
As I see it, the question is more related to "what to do with tables, that are related by foreign keys".
Lets say you have Users and Articles tables, where each article has a specific owner associate by user_id foreign key. In this case, when populating the Article entity, I would only retrieve the user_id value instead of pulling in all the information about the user.
But in your example with Users and UserEmails, the emails seem to be a part of the User entity, and something that you would often call via $user->getEmailList().
TL;DR
I would do this in two queries, when populating User entity:
select all you need from Users table and apply to User entity
select all user's emails from the UserEmails table and apply it to User entity.
P.S
You might want to look at data mapper pattern for "how" part.
In my opinion you should fetch all your fields at once, and divide queries in a way that makes your code easier to read/manage.
When we're talking about one query or two, the difference is usually negligible unless the combined query (with JOINs or whatever) is overly complex. Usually an index or two is the solution to a very slow query.
If we're talking about one vs hundreds or thousands of queries, that's when the connection/transmission overhead becomes more significant, and reducing the number of queries can make an impact.
It seems that your framework suffers from premature optimization. You are hyper-concerned about fetching too many fields from a row, but why? Do you have thousands of columns or something?
The time consuming part of your query is almost always the lookup, not the transmission of data. You are causing the database to do the "hard" part over and over again as you pull one field at a time.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I am currently trying to get values from tables I have in a webpage into a database using PHP. However, the order of the values inside each box is important, so I want the first box to be ranked 1 and the second box to be ranked 2 and so on... There is no limit to the number of items in each box. There may be as many as 100 or 0. Each item in each box is dragged from a bank of items into the table, which represents a topic. The tables are the output of the interface.
So example table:
Rank1
Rank2
Rank3
I've currently tried dumping the entire page once the user fills it in into a text file and parsing it from there but i'm looking for a more functional and practical way of doing it.
If I understand your goal correctly, you have two sections on your webpage. A word bank and a <table>. A user can drag and drop items from the word bank to a cell in your <table>. Next you want the order of the contents of the cell to be preserved when the data is saved to a database-table.
Given the description you have provided, it seems you may be new to using databases. It is not a problem but you will need to do some study on how databases work and how to use them.
Again, if I understand correctly, your <table> looks like the following:
| topic-1 | topic-2 | topic-3 |
-------------------------------
| ---A--- | ---J--- | ---V--- |
| ---B--- | ---J--- | ---X--- |
| ---C--- | NULL | ---Y--- |
| NULL- | NULL | ---Z--- |
To move this into a database you need to create a database, and some table, for example MyDataTable. Next that table may have three columns: id, contents, category.
Here is some info on Mysql Insert.
INSERT INTO MyDataTable(`id`, `contents`, `category`)
VALUES (1, A, Topic-1)
You will need to format that call to work correctly via php, but that is the general idea. In your php code you will need to iterate over the elements in the order you want, and you can use the id to refer to your order... Alternatively you could add another column to your database-table and have that refer to your order, which would allow you to use some other value, perhaps auto-increment, as the primary key.
I would recommend becoming comfortable with MySQL if you aren't already, before tackling your project's specific needs. Namely, INSERT, DELETE, UPDATE, SELECT and WHERE will almost certainly be necessary MySQL functions.
One resource I found very helpful in grasping MySQL is this book, SQL Antipatterns: Avoiding the Pitfalls of Database Programming .
Using the phpMyAdmin page can be very helpful in debugging SQL queries, once the query syntax is correct, you can translate it to php and incorporate your dynamic variables. Also if you store your sql-syntax in php as $sql, using var_dump($sql) can also be a great help when debugging sql syntax.
In programming, iterate over, typically refers to creating a for-loop to iterate, or step through 1-by-1, each of the items of an array or similar container.
$MyArray = array();
$MyArray = GetTableContents(); //You have to write this function.
for ($idx = 0; $idx < count($MyArray); $idx++)
{
// do my stuff, like, Insert into my DB-table.
}
In order for the code above to work, you need to fill MyArray with the contents from your <table>. In the example code above, the $idx, could be used as your id.
In addition to MySQL, it seems it would also be worth your time to learn more about php programming. Read simple tutorials, how-to's, and books. There are numerous resources on the internet about php. One such example is here.
I hope this is helpful.
it is just a simple question but i want to solve it as best as possible.
There will be a table in html, which would be filled with data from a mysql query,
for example:
name | street | zip
What i want is to make this changeable, so that user can directly change the results -> click on save -> Update via mysql.
My plan was now, to display the data in input fields which are named like this:
name_id | street_id | zip_id
By clicking on save i would perform a while-loop to get all names, streets, and zips of the id and perform an mysql update afterwords. I know that this would be possible that way (i already used this 1 time).
But: is there a more easier and better solution for this problem?
BR
If you plan to use javascript this is the way to do it!
I was just working with this a few hours ago.
http://www.jeasyui.com/extension/edatagrid.php
Updating all elements could cause heavy load on your server, depending on the amount of data you have stored. A more performance-friendly solution would be to "save" the row keys of the data that you changed. If you do this, you would only update the rows that actually changed, and not all rows!
I'm making an online quiz with php and mysql and need a bit of help deciding how to design the database for optimal insert of questions/answers and to select questions for the quiz. The table will hold 80 questions each with 4 possible options plus the correct answer.
When retrieving the questions and options from the database I will randomly select 25 questions and their options.
Is it better to make a single column for all questions, options, and correct answers? For example:
ID | Q | OPT1 | OPT2 | OPT3 | OPT4 | ANS
Or would it be better to make a column for each individual question, option, and correct answer? For example:
Q1 | Q1_OPT1 | Q1_OPT2 | Q1_OPT3 | Q1_OPT5 | Q1_ANS | Q2 | Q2_OPT1 | Q2_OPT2...
It'd be better to store the possible answers in a seperate table. This allows you to have any amount of answers per question instead of just 4. It also allows questions to have a different number of answers. If you have more than one quiz, you may also want a Quizes Table.
Quizes:
id
name
Questions:
id
quiz
prompt
Answers:
id
question
prompt
QuizResult (someone taking a quiz)
id
quiz
// other information about the quiz taker, possibly including the time
Now the correct answer thing gets a lot more tricky. I prefer the higher implementations here:
Each question has a value and each answer has value
A system I recently worked with you could assign a point value for each question and each answer. Incorrect answers often got 0, correct answers got the full amount. You could also have partially-correct answers using this method. This is the method I would go with.
You could go and say every question is worth 10 points or you could assign different weights to different questions:
Questions:
id
quiz
prompt
value (you can make this question worth more or less)
Answers:
question
prompt
value (you can make this answer worth more or less)
Store the correct answer in the Answers Table
A more simple (but less robust) solution is to simply say which answer is correct in the Answers table.
Answers:
question
prompt
is_correct
Store the correct answer in the Questions Table
I wouldn't recommend it. When you create a question, it won't have a correct answer until you insert one. This means at least 3 queries to correctly make a question. If you use foreign key dependencies, this will quickly get annoying.
Go with option 1 where you are having one row for each question/options/answer.
Option 2 does not make any sense. Every time you want to add/delete a question you'll be modifying the database schema!! And you'll have just one row always !!
Go for your first option. It is the most normalised option, but that isn't necessarily a clinching argument. But the virtues of the normalised design are manifold:
it is a piece of cake to include new questions into your quiz portfolio. (The other option requires adding new columns to the table).
it is simple to write the select statement which returns the result set. (the alternative option requires a dynamic SQL)
it is easy to write a GUI which displays the questions and answers, because each displayed set of text maps to the same coilumn_names.