MySQL recursive-query replacement in PHP - php

Since it looks like recursive queries aren't possible in MySQL, I am wondering if there is a solution to get the same information that also limits the number of queries I make to the database. In my case I have what amounts to a tree and given a node, I make a path back to the root and save the name of the nodes as I go. Given a table like this:
id | parent
-------------
1 |
2 | 1
3 | 1
4 | 2
5 | 2
6 | 5
I want to select all ids on the path from 6 back to 1 (6,5,2,1). Since the total length of the path is unknown I would assume that the only way to do this is taking the results from one query and build a new query until I am back at the root. Then again it has been a couple years since I last used MySQL so it wouldn't surprise me if I am a little out of touch. Any help would be appreciated.

Since it looks like recursive queries aren't possible in mySQL
mySQL doesn't support the 'CONNECT BY' operator, true - but you can implement recursive procedures/functions using mysql and return result sets from them.

Related

PHP, Python processing or MySQL processing on a large date set?

I have 2 million rows in a myqsl DB which have multiple columns of contacts as phone_1, phone_2 upto phone_10.
These phone no. may or may not duplicate.
I intend to group them together..as
ID Contact_1 Contact_2 Contact_3
P1 1 2 3
P2 5 6 7
P3 2 8 9
result should be:
ID Contact_1 Contact_2 Contact_3 Group
P1 1 2 3 1
P2 5 6 7 2
P3 2 8 9 1
P3 11 12 13 3
P3 7 21 22 2
Now where should I do the processing part ...PHP/Python or mysql.
i.e. select the entire data in php script and create an arrray and process tha array and then use insert query.
OR
select the entire data in php script and then use UPDATE(with a logic to create groups) query.
??
I have group field in DB table.
It depends, I'd say mostly on how comfortable you are with each language. I would probably do this with PHP, but that's the language I know best.
You can certainly do it purely with MySql, and the operation would probably run faster, but it might be easier to debug and test each step in PHP or Python.
Regardless, I'd recommend first creating a data subset, maybe 1000 or 2000 rows from the table and running everything against that until you're happy with the results. It'll be much much faster and you'll see mistakes sooner.
Also, I'd avoid running anything you're worried about being slow on a production server.

MySQL using RegEx to update/select columns

I searched in the internet for an answer to select every columns that matches regex pattern. I didn't find one, or maybe I did, but I didin't understand it, because I'm new to DataBases. So here's the sql I was trying to run:
UPDATE `bartosz` SET 'd%%-%%-15'=1
(I know it's bad)
I have columns like:
ID | d1-1-15 | d2-1-15 | d3-1-15 | d4-1-15 ... (for 5 years, every month, and day)
So is there a way to select all columns from 2015?
I know i can loop it in php so the sql would look like:
UPDATE `bartosz` SET 'd1-1-15'=1, 'd1-1-15'=1, 'd3-1-15'=1 [...]
But it would be really long.
Strongly consider changing your approach. It may be technically possible to have a table with 2000 columns, but you are not using MySQL in a way that gets the most out of the available features such as DATE handling. The below table structure will give better flexibility and scaling in most use cases.
Look into tables with key=>value attributes.
id employee date units
1 james 2015-01-01 2
2 bob 2015-01-01 3
3 james 2015-01-02 6
4 bob 2015-01-02 4
With the above it is possible to write queries without needing to insert hundreds of column names. It will also easily scale beyond 5 years without needing to ALTER the table. Use the DATE column type so you can easily query by date ranges. Also learn how to use INDEXes so you can put a UNIQUE index on the employee and date fields to prevent duplication.

Iterating through items and subitems - knowing when to stop [duplicate]

This question already has an answer here:
recursive self query
(1 answer)
Closed 9 years ago.
I'm building a task system in php/mysql, imagine I have the following structure:
id | parentid
1 0
2 1
3 1
4 1
5 4
A parentid of 0 means there are no sub items.
So basically, I need to query all items that have a parentid of 1.
In a tree view example I'd get:
1
--2
--3
--4
But I also need to grab all the other subitems:
1
--2
--3
--4
---5
I hope this clears up what I need, this only goes into 3 levels, but I could very well have a huge number of levels.
How should I approach this in MYSQL? Getting a full list of all items with a specific parentid and ALL the other subitems?
Is this even a possible without knowing a limit? Maybe approach this via server side? (but then again, when to stop?)
This question has already been answered. Best way to go about this is using recursive query which MySQL doesn't support.
Here is a workaround for it: Using MySQL query to traverse rows to make a recursive tree
You could do it in PHP or any other language you use for server side but it would take a lot of requests to get all the data you need.

Altering thousands of records every page refresh

I am starting to think about my new project and I've found a couple of speed issues, so I hope you can help me with selecting a good and elegant way to code it.
Each user has in the database records of "places" he has visited. Each place has "schools" - a number of schools in this particular place. Each school has classes. Each class may end its "learning year" at different times, so it's number should increment if date is >= end of learning year.
So we have such a database:
"places" table:
place | user_id |
-----------------
1 | 4 |
2 | 4 |
User no 4 visited place no 1 and 2
"schools" table:
school | place |
----------------
5 | 2 |
6 | 2 |
Place 2 has two schools - with id 5 and 6.
"class" table:
class | school | end_learning | class_number
---------------------------------------------
20 | 5 | 01.01.2013 | 2
21 | 5 | 03.01.2013 | 3
22 | 5 | 05.01.2013 | 4
School 5 has 3 classes with ids 20, 21, 22. If date is greater than 01.01.2013, the class number of class 20 should be incremented to 3 and end learning date changed to 01.01.2014. And so on.
And now we got into the problem - if there is 1000 places, each with 100 schools, each with 10 classes we got 1000000 records. It's a lot. Because all I have presented is just a simple example I have to consider updating whole database every time user refreshes the page so I'm afraid it might be laggy on that amount of records.
I also can serialize class into one field in school table:
school | place | classes
-------------------------------------------------------------------------
5 | 2 | serialized class 20, 21, 22 with end_learning field and class number
6 | 2 | other serialized classes from school 6
In that case I get 10 times less records but each time I have to deserialize data, check dates and if it's less than now alter it, serialize and save to database. The second problem is that I have to select all records from db to manipulate them not only all those need to be altered.
I am also thinking about having two databases: One with records that might need change in further future, and second that might need change in next 24hrs (near future). Every 24hrs all the classes which end learning in next 24 hrs are moved to "near future" db so every refresh of the page works on thousands of records, not hundreds of thousands or millions. Instead of that it works on millions of records (further future) to create "near future" table only once per day.
What do you think about all those database schemas? Maybe you have a better idea?
I don't quite understand the business logic or data model you outline - but I will assume you have thought this through.
Firstly, RDBMS solutions like MySQL are really, really good at managing large numbers of records, as long as the data you are working with is relational. As far as I can tell, you will be searching across many records, but only updating a few (a user will only be enrolled in a limited number of classes); I don't see this as a huge problem.
Secondly, it's nearly always better to go with the "standard" relational model until you can prove it doesn't meet your performance needs than to go for "exotic" solutions at the start off (I class your serialization and partitioning solution as "exotic" for the purpose of this answer). A lot of time and energy has gone into optimizing performance of SQL; if there were a simple alternative, it would be part of the standard solution. There are, of course, points at which the standard relational model doesn't scale (Facebook-size traffic, for instance), or business domains where the relational model doesn't really fit (documents, graphs). However, all the alternatives have benefits and drawbacks just like "standard" MySQL.
Thirdly, the best way to deal with possible performance issues is, well, to deal with them. In code. Build a test rig, create a schema according to the relational model, populate it with test data (e.g. using DbMonster), throw some load at it (e.g. using JMeter) and tune your schema and queries to prove your situation doesn't fit the standard solution. Only go for something exotic if you really can prove that you can't play nice with standard, relational database stuff.

Time Machine for Business Intelligence (PHP/MySQL)

Currently I am developing a time machine for a open-source Business Intelligence software from scratch using PHP/MySQL.
My time-machine table is used by all other tables that need date info (such as orders, products, etc.) and they binding with time_id. So its MySQL table like this:
time_id | timestamp | day | week | month | quarter
1 1303689654 25 17 4 2
2 1303813842 26 17 4 2
...
Order table binding like this:
order_id | time_id ...
3123 2
...
edit: it's similar to STAR SCHEMA.
The problem is getting TIME (13:45) information as well. Usually I don't need this, but like orders, and sometimes a couple of tables need this HOUR/MINUTE infomation.
How can I solve this problem cleverly? I have a couple of solutions, but first i want to see your opinions..
Why don't you simply store timestamps in your other tables?
Or, if you want to keep the dates table, simply add a TIME field to your other tables which need it.
If I understand your timestamp correctly, you can probably just go:
echo date('H:i.s',1303689654);
edit
What are you trying to do? After re-reading your question you may be looking for the JOIN keyword in SQL (brief tute)

Categories