MySQL store string with variable to be filled later - php

I'm wondering if it is possible to store variables within a string in a MySQL database and later fill those using (straightforward) PHP. I'll be using this for an action-log of an online management system. I was thinking about implementing it as follows:
Tables:
Actions
+------+-----------------------------+-------------------+
| id | text | datatype |
+------+-----------------------------+-------------------+
| 1 | $a reset the password of $b | [user,user] |
| 2 | $a added $b to group $c | [user,user,group] |
| etc | etc | etc |
+------+-----------------------------+-------------------+
and
Actions_log
+------+-----------------------------+-------------------+
| id | action_id | variables |
+------+-----------------------------+-------------------+
| 1 | 1 | [3281,1008] |
| 2 | 1 | [8210,0145] |
| 3 | 2 | [3281,1008,12] |
+------+-----------------------------+-------------------+
And then doing some PHP to end up with a string like this:
3281 reset the password of 1008
I came up with 2 solutions:
str_replace("$a",$data);
Using $data[0], $data[1] and $data[2], etc, as variables and fill the $data array with the data from the table.
I'm not really familiar with PHP yet, the above mentioned solutions don't seem very efficient and even cumbersome. There must be a proper way to do something like this. Anyone has any idea's to point me in the right direction?
Thanks!

Related

MySQL Accounting Code Database Structure

I have a question on making the effective database structure for accounting code. The result I was expecting is this
| ID | Code | Name | Parent |
| 1 | 1 | Assets | |
| 2 | 1 | Tangible Fixed Assets | 1 |
| 3 | 1 | Building | 2 |
| 4 | 2 | Intangible Fixed Assets| 1 |
| 5 | 1 | CopyRights | 3 |
I've been thinking about making 3 tables such as tbl_lvl1 for main parent, tbl_lvl2 as first child and tbl_lvl3 as second child. I found about recursive query, which is just only using 1 table, but it's kind of difficult making recursive query in MYSQL.
And the result I want to view in PHP, is something like this
| Code | Name |
| 1 | Assets |
| 11 | Tangible Fixed Assets |
| 111 | Building |
| 12 | Intangible Fixed Asset |
| 121 | CopyRights |
Which structure I should make? Using 3 table or 1 table ? Thank you
You're looking for a search tree, and I'd especially suggest a B-tree.
A search tree, generally spoken, allows you to hierarchically search for all sub-nodes in a single query through nested intervals.
There are literally dozens of implementations, so you don't need to dig deep into the details, even though I would suggest it, as it's a major data structure that you should be used to.

How would I write the sql query in php to get this result?

First of all I am currently trying to learn php and I thought I would build a basic maintenance management app to better grasp everything I see in tutorials, and I hit a roadblock. I've been trying to get this to work following various tutorials online but I had no success so far, so I thought I would ask for help here. I really hope you can help me.
What I would like to know is how can I write the php & mysql to write the data from the first 3 table to the desired_table from below ?
Clients
------------------------------
client_id | client_name
------------------------------
1 | client_1
------------------------------
2 | client_2
------------------------------
3 | client_3
Equipments
------------------------------
eq_id | eq_name
------------------------------
1 | pc
------------------------------
2 | laptop
------------------------------
3 | printer
Operations
------------------------------------------------
op_id | op_desc
------------------------------------------------
1 | dust cleaning
------------------------------------------------
2 | changing processor cooling paste
------------------------------------------------
3 | cpu replacement
------------------------------------------------
4 | display replacement
------------------------------------------------
5 | dvd-rom replacement
------------------------------------------------
6 | ram replacement
------------------------------------------------
7 | cartrige replacement
Desired_table
-------------------------------------
id | client_id | eq_id | op_id |
-------------------------------------
1 | 1 | 1 | 1 |
-------------------------------------
2 | 1 | 1 | 2 |
-------------------------------------
3 | 1 | 1 | 3 |
-------------------------------------
4 | 1 | 1 | 5 |
-------------------------------------
5 | 1 | 2 | 1 |
-------------------------------------
6 | 1 | 2 | 2 |
-------------------------------------
7 | 1 | 2 | 4 |
-------------------------------------
8 | 2 | 1 | 1 |
-------------------------------------
9 | 2 | 1 | 2 |
-------------------------------------
10| 2 | 1 | 3 |
-------------------------------------
11| 2 | 1 | 5 |
-------------------------------------
12| 2 | 3 | 1 |
-------------------------------------
13| 2 | 3 | 7 |
I thought I would have a form with input fields for the client data and the equipment data and operations data I would have in dropdowns. When I would select an equipment a new dropdown would appear with the operations, and then submit it.
Hope this doesn't get marked as too broad subject :)
Using the code from your bitbucket this should do it:
$page = $db->prepare("
INSERT INTO new_table_name (column_name1, column_name2, column_name3)
VALUES (:col1, :col2, :col3)
");
$page->bindparam(':col1', $value1);
$page->bindparam(':col2', $value2);
$page->bindparam(':col3', $value3);
$page->execute();
if($page->rowcount() > 0){
echo "Inserted a new row";
}
Here is a example, replace 'new_table_name' to the name off the new table and change the column names.
After that simiply change $value1, 2 and 3 to the variables that contain the value you want to insert and you're good to go.
If you want to know if the insert was succesful just check with $page->rowcount(). If the rowcount is more than 0 it was succesful.
And just to clarify, this is called a prepared statement if you don't know this yet. What the code does is this:
Prepare tells the server what you're planning to do. This adds a really strong layer off protection since basic sql injection are close to impossible to do.
After that you bind the variables to the given parameters (Other syntax is possible, I just prefer this one). The code takes care off quotations so just put the parameter in there.
Execute the actual query
And just for good measure, you can add 2 extra parameters to bindparam.
In the third you can define a variable type, PDO::PARAM_STR and PDO::PARAM_INT block any other type off variable.
The 4th lets you set a max length, if the variable is longer it will get blocked.
This will look like this:
$page->bindparam(':col1', $value1, PDO::PARAM_STR, 100);
//block anything which isn't a string or longer than 100 characters

Assigned multiple users to a 'task'

Okay so I'm creating a task manager for my company. A user can assign assign a task to multiple other users. So I've though of 2 ways of implementing this.
This is my tasks table for option one (at least the columns that are important in this discussion ):
----------------------------------------------
| id | assigned_to | assigned_from |
---------------------------------------------
| 1 | 1,3,6 | 4 |
--------------------------------------------
| 2 | 1,4 | 2 |
---------------------------------------------
So here I pretty much just comma separate each user_id that is assigned to this particular task
Option 2:
----------------------------------------------------------
| id | task_id | assigned_to | assigned_from |
------------------------------------------------------------
| 1 | 335901 | 1 | 4 |
-----------------------------------------------------------
| 2 | 335901 | 3 | 4 |
-----------------------------------------------------------
| 3 | 335901 | 6 | 4 |
-----------------------------------------------------------
| 4 | 564520 | 1 | 2 |
-----------------------------------------------------------
| 4 | 564520 | 4 | 2 |
-----------------------------------------------------------
So as you can see here instead of putting the assiged_to is's here I just create a task id which is a random number and then I can groupBy 'task_id'. This is currently they way I have built it but for some reason it feels like it might screw me over in the future (not that option one doesn't give me the same feeling). So my question is which way do you guys recommend or is there maybe a different better way that I could be doing this?
Option 2 ist the better solution since you can acutally work with the table. You may e.g. create another table Tasks with
Task_id | Task_name | Budget | ...
Or a table with user-IDs for assigned_to and assigned_from. All these tables can be joined together if you use 2nd Option.
btw it is the correct normalization form
You can use Option 2 and normalize further if tasks are always assigned by/from the same person.
Tasks table:
task_id | assigned_from
1 | 4
2 | 2
The Assignees table then doesn't need to have the assigned_from since it's always the same for that task_id:
id | task_id | assigned_to
1 | 1 | 1
2 | 1 | 3
3 | 1 | 6
4 | 2 | 1
5 | 2 | 4

MySQL query how to get list of all distinct values from columns that contain multiple string values?

I am trying to get a list of distinct values from the columns out of a table.
Each column can contain multiple comma delimited values. I just want to eliminate duplicate values and come up with a list of unique values.
I know how to do this with PHP by grabbing the entire table and then looping the rows and placing the unique values into a unique array.
But can the same thing be done with a MySQL query?
My table looks something like this:
| ID | VALUES |
---------------------------------------------------
| 1 | Acadian,Dart,Monarch |
| 2 | Cadillac,Dart,Lincoln,Uplander |
| 3 | Acadian,Freestar,Saturn |
| 4 | Cadillac,Uplander |
| 5 | Dart |
| 6 | Dart,Cadillac,Freestar,Lincoln,Uplander |
So my list of unique VALUES would then contain:
Acadian
Cadillac
Dart
Freestar
Lincoln
Monarch
Saturn
Uplander
Can this be done with a MySQL call alone, or is there a need for some PHP sorting as well?
Thanks
Why would you store your data like this in a database? You deliberately nullify all the extensive querying features you would want to use a database for in the first place. Instead, have a table like this:
| valueID | groupID | name |
----------------------------------
| 1 | 1 | Acadian |
| 2 | 1 | Dart |
| 3 | 1 | Monarch |
| 4 | 2 | Cadillac |
| 2 | 2 | Dart |
Notice the different valueID for Dart compared to Matthew's suggestion. That's to have same values have the same valueID (you may want to refer to these later on, and you don't want to make the same mistake of not thinking ahead again, do you?). Then make the primary key contain both the valueID and the groupID.
Then, to answer your actual question, you can retrieve all distinct values through this query:
SELECT name FROM mytable GROUP BY valueID
(GROUP BY should perform better here than a DISTINCT since it shouldn't have to do a table scan)
I would suggest selecting (and splitting) into a temp table and then making a call against that.
First, there is apparently no split function in MySQL http://blog.fedecarg.com/2009/02/22/mysql-split-string-function/ (this is three years old so someone can comment if this has changed?)
Push all of it into a temp table and select from there.
Better would be if it is possible to break these out into a table with this structure:
| ID | VALUES |AttachedRecordID |
---------------------------------------------------------------------
| 1 | Acadian | 1 |
| 2 | Dart | 1 |
| 3 | Monarch | 1 |
| 4 | Cadillac | 2 |
| 5 | Dart | 2 |
etc.

Save quiz alternatives as JSON string or individual rows?

I'm making a quiz. Each question consists of a question, three alternatives, and one of them are correct. The server should output HTML (not JSON that JS is going to parse), and the user chooses an answer.
The reason why I'm in doubt is that the person who makes the quiz is sending the alternatives over JSON. And if you want to edit any of the alternatives later on, you just parse the JSON, do your changes and send it to the server. Then the server will just update the alternatives "cell".
However when the user takes the quiz, the server has to run through the array to find the right answer. If the answers are stored in their own separated row (many-to-many), the server could just query for the right answer.
In addition to this, JSON would result in saving the alternatives in a TEXT column compared to many small VARCHARS if one uses a many-to-many relationship.
What is the most efficient way to do it? (Speed)
What is the most convenient way, and most accepted way to do it?
Well, I would have say that your table should look like this:
+------+------------+--------+--------+--------+--------------+
| ID | Question | Ans1 | Ans2 | Ans3 | CorrectAns |
+------+------------+--------+--------+--------+--------------+
| PKey | text | text | text | text | text |
+------+------------+--------+--------+--------+--------------+
| 1 | π = ? | 3.1415 | 2.2465 | 5.6598 | 3.1415 |
+------+------------+--------+--------+--------+--------------+
And your query would be:
SELECT (CorrectAns = %enteredanswer%) FROM QuizTable WHERE ID=%questionid%
Its pretty easy to convert json to this table, and vice-versa.
EDIT: For an undefined number of alternatives:
You could have a Question table, and an Options table like so:
Question:
+-------+------------+---------------+
| QID | Question | CorrectAnsID |
+-------+------------+---------------+
| PKey | text | FKey,integer |
+-------+------------+---------------+
| 1 | π = ? | 2 |
+-------+------------+---------------+
Options:
+-------+--------------+--------------+
| OID | OptionText | QuestionID |
+-------+--------------+--------------+
| PKey | text | FKey,Integer |
+-------+--------------+--------------+
| 1 | 3.5600 | 1 |
+-------+--------------+--------------+
| 2 | 3.1415 | 1 |
+-------+--------------+--------------+
| 3 | 3.4567 | 1 |
+-------+--------------+--------------+
| 4 | 3.7894 | 1 |
+-------+--------------+--------------+
| 5 | 3.9874 | 1 |
+-------+--------------+--------------+
This might be faster to work than the json method, but more difficult to implement (joins and stuff to write), so if its a quick, smaller scale project, I'd go with the json method.

Categories