I have a comma delimited list that im storing in a varchar field in a mysql table.
Is it possible to add and remove values from the list directly using sql queries? Or do I have to take the data out of the table, manipulate in PHP and replace it back into mysql?
There is no way to do it in InnoDB and MyIsam engines in mysql. Might be in other engines (check CSV engine).
You can do it in a stored procedure, but, not recommended.
What you should do to solve such an issue is to refactor your code and normalize your DB =>
original table
T1: id | data | some_other_data
1 | gg,jj,ss,ee,tt,hh | abanibi
To become:
T1: id | some_other_data
1 | abanibi
T2: id | t1_id | data_piece
1 | 1 | gg
2 | 1 | jj
3 | 1 | ss
4 | 1 | ee
5 | 1 | tt
6 | 1 | hh
and if data_piece is a constant value in the system which is reused a lot, you need to add there a lookup table too.
I know it looks more work, but then it will save you issues like you have now, which take much more time to solve.
Related
I have 150+ tags (more in future), 18000+ of different content to display and 380+ users (more in future).
What will be the best way to display content to users according to the Tag value for the user?
I thought of storing all tag activities in the database like:
________________________________
| Sr. | User_Id | Tag_Id | Int. |
|________________________________|
| 1 | 152 | 18 | 15 |
| 2 | 152 | 24 | 8 |
| 3 | 18 | 127 | 4 |
|________________________________|
In database Int. means how many times the user is interested in the posts having Tag_Id.
As the user clicks Interested? the Int. column will be +1 for that user and that tag.
If I store the values in the database, the database will have huge content and huge traffic and will need large storage too. (108K values only for now then imagine the stage of values after 2 years.)
Any other best alternatives?
I am using PHP & MySQL.
For the best RM model solution, you will have to give some more information about the complete model. But as I see it now, this is the best solution. You can remove the id and set the primary key to user_id and tag_id (both).
My table User
+----+-----------+---------+--------+---------+------+-------+
| id | name | email | number | call_no | chek | Extra |
+----+-----------+-------+----------+---------+------+-------+
| 1 | one | a#a.com | 123 | 1164 | 1 | 1,2 |
+----+-----------+---------+---------+---------+------+------+
| 2 | two | a#a.com | 123 | 1164 | 1 | 2,1 |
+----+-----------+---------+---------+---------+------+------+
I have the field called Extra it contains the value 1,2
what is my question is ?
I need to match the 1,2 in the table id and myresult like one,two from the user table
For simple example query.what im tried is in below ?
select name from user Extra in('1,2');
My expected output is
one,two
If i tried to do in explode and if i run it in loop i can get the result but i need this in sql is it possible to get it?
You should have a separate table with one row per id and each value of extra. This is called a junction table. SQL has a great data structure for storing lists of things, called a table not a string. And, storing numbers as characters is even worse.
You can, however, do what you want with a join and aggregation:
select id, group_concat(e.name) as names
from table t left join
table e
on find_in_set(t.id, e.extra) > 0
group by t.id;
I'm displaying a record set using Datatables pulling records from two tables.
Table A
sno | item_id | start_date | end_date | created_on |
===========================================================
10523563 | 2 | 2013-10-24 | 2013-10-27 | 2013-01-22 |
10535677 | 25 | 2013-11-18 | 2013-11-29 | 2013-01-22 |
10587723 | 11 | 2013-05-04 | 2013-05-24 | 2013-01-22 |
10598734 | 5 | 2013-06-14 | 2013-06-22 | 2013-01-22 |
Table B
id | item_name |
=====================================
2 | Timesheet testing |
25 | Vigour |
11 | Fabwash |
5 | Cruise |
Now since the number of records returned is going to turn into a big number in near future, I want the processing to be done serverside. I've successfully managed to achieve that but it came at a cost. I'm running into a problem while dealing with filters.
From the figure above, (1) is the column whose value will be in int (item_id), but using some small modifications inside the while loop of the mysql resource, I'm displaying the corresponding string using Table B.
Now if I use the filter (2), it is working fine since those values come from Table A
The Problem
When I try to filter from the field (3), if I enter a string value such as fab it says no record found. But if I enter an int such as 11 I get a single row which contains Fabwash as the item name.
So while filtering I'm required to use the direct value used in Table A and not its corresponding string value stored in Table B. I hope the point that I'm putting across is understandable because it is hard to explain it in words.
I'm clueless on how to solve the issue.
I want to insert into the cart table
**orderId** | cartId | cartDate | cartStatus
____________________________________________
1 | 1 | 20120102 | complete
2 | 2 | 20120102 | complete
3 | 3 | 20120102 | complete
4 | 4 | 20120102 | complete
using the auto increment value orderId from the order table
**orderId** | orderStatus | secret | sauce
____________________________________________
1 | 7 | 020200202 | bbq
2 | 6 | 020200202 | bbq
3 | 6 | 020200202 | t
4 | 4 | 020200202 | m
INSERT INTO ordertable VALUES(null,7,020200202,bbq)
but then using the orderId (which will now be 5)
INSERT INTO carttable VALUES(orderId,20120102,complete)
However,
this insert must be done as the same query. If I use mysql_last_id (php) there is an opportunity for someone else to insert into the database before my cart insert is executed. Or the connection might timeout. The database is MyISAM (and I can not change this, 3rd party solution).
Thank you,
J
I think your concern about using mysql_last_id is unfounded - it will return the last id for the current connection, not the last id globally across all connections.
So unless you have multiple threads sharing the same database connection or you perform another identity insert on the same connection before calling mysql_last_id, you should have nothing to worry about.
ETA: You could do this by sending multiple queries at once, like this:
INSERT INTO ordertable VALUES(null,7,020200202,bbq);
INSERT INTO carttable VALUES(LAST_INSERT_ID(),20120102,complete);
But if you are using mysql_query it usually won't let you send multiple queries in the same call (mostly as a security measure to try to prevent SQL injection).
I'm creating a table for allowing website users to become friends. I'm trying to determine which is the best table design to store and return a user's friends. The goal is to have fast queries and not use up a lot of db space.
I have two options:
Have individual rows for each friendship.
+----+-------------+-------------------+
| ID | User_ID | Friend_ID |
+----+-------------+-------------------+
| 1 | 102 | 213 |
| 2 | 64 | 23 |
| 3 | 4 | 344 |
| 4 | 102 | 2 |
| 5 | 102 | 90 |
| 6 | 64 | 88 |
+----+-------------+-------------------+
Or store all friends in one row as CSV
+----+-------------+-------------------+
| ID | User_ID | Friend_ID |
+----+-------------+-------------------+
| 1 | 102 | 213,44,34,67,8 |
| 2 | 64 | 23,33,45,105 |
+----+-------------+-------------------+
When retrieving friends I can create an array using explode() however deleting a user would be trickier.
Edit: For second method I would separate each id in array in php for functions such as counting and others.
Which method do you think is better?
First method is definitely better. It's what makes relational databases great :)
It will allow you to search for and group by much more specific criteria than the 2nd method.
Say you wanted to write a query so users could see who had them as a friend. The 2nd method would require you to use IN() and would be much slower than simply using JOINS.
The first method is better in just about every way. Not only will you utilize your DBs indexes to find records faster, it will make modification far far easier.
Breaking from 1st normal form is usually not desirable because
Easy to Orpahned ids
Easy to insert invalid data types
Updates can require full table scans
Increases concurrency issues
No way to create the key (user_id, friend_id)
Use the power of the relational database. Definitely go with the first approach. MySQL is faster than you think, and it regularly deals with VERY large datasets.