I'm building a PHP/MySQL app where users can log in and search for media assets. They can also save searches and create lightboxes (collections of assets). Finally, they can create user groups.
Does it make more sense to query all at once, at log in, for the id's for their saved searches, lightboxes, and groups and save those in session vars? Or to perform the queries when they first hit the appropriate pages? I'm looking for efficiency, and the sessions seem the way to go, but am I overlooking anything?
Biggest Rule: Only put in the session what you need in the session
I don't think it would be wise at all to put everything you need in the session all at once because you'll have a lot of occurrences where that isn't needed. The user might not stay long enough to make use of all the data in there, so you just wasted time and resources putting it there.
Put your information in there on demand (when they go to each page that requires that information).
Always keep your session object neat and slim and your performance will thank you.
Querying all at login is a bad idea. First it slows down login and 2nd it creates a static workload on your SQL server for every login.
If you query when applicable, you have a varied load. (even if you cache the results to be used later)
Also if you store results in sessions, then you are increasing the memory used for each request for that user.
There are many things that can be good for your particular site but we need more data to be able to answer that better.
Query only what you need and when is necessary.
Short example that proves that all in one query is wrong:
If you query for login and user data and the login goes bad, the rest of the query will not be used.
Related
I was hoping to get your input on a CMS that I am creating. How it is currently setup, on a visitors first page load the system queries the "site" table and pulls down any site wide data (ie. Site ID/Site name/Site wide hooks etc.). This information is stored in PHP session and that table does not get queried again for the remainder of the users visit.
Does this sound acceptable? I like the idea of saving an unnecessary db query on every page load however, if the site has a large amount of hooks, this session var could get large (unlikely but possible).
For extra information, the system currently runs a config class that could store some site data (thus preventing even the first db query) however I want the plugin system to easily be able integrate hooks into this CMS so I decided a DB route was the way to go.
I would appreciate your input. Thanks
There's no need in overcomplicating things, K.I.S.S will serve you good here. Start optimizing when you actually need it. You should also remember that the database will most likely cache the query and the result if it's done multiple times so there's no guarantee that you will save any time at all.
I'm in the design phase of a website and I have a solution for a feature but I don't know if it will be the good one when the site, hopefully, grows. I want the users to be able to perform searches for other users and the results they find must be ordered: first the "spotlighted" users, then all the rest. The result must be ordered randomly, respecting the previously mentioned order, and with pagination.
One of the solutions I have in mind is to store the query results in a session variable in the server side. For performance, when the user leaves the search this variable is destroyed.
What will happen when the site has thousands of users and every day thousands of searches are performed? My solution will be viable or the server will be overloaded?
I have more solutions in mind like an intermediate table where n times by day users are dumped in the mentioned order. This way there is no need to create a big array in the user's session and pagination is done via multiple queries against the database.
Although I appreciate any suggestions I'm specially interested into hear opinions from developers seasoned in transited sites.
(The technology employed is LAMP, with InnoDb tables)
Premature optimization is bad. But you should be planning ahead. You dont need to implement it. But prepare yourself.
If there are thousands of users searching this query everyday then caching the query result in session is not a good idea. Cause same result can be cached for some users while other needs to execute it. For such case I'd recommend you save the search result in user independent data structure (File, memory etc).
For each search query save the result, creation date, last access date in your disk or in memory.
If any user searches the same query show the result from cache
Run a cron that invalidates the cache after sometime.
This way frequent searches will most time promptly available. Also it reduces the load on your database.
This is definitely not the answer you are looking for, but I have to say it.
Premature Optimization is the root of all evil.
Get that site up with a simple implementation of that query and come back and ask if that turns out to be your worst bottleneck.
I'm assuming you want to decrease the hitting on the DB by caching search results so other users searching for the same set of factors don't have to hit the DB again--especially on very loose query strings on non-indexed fields. If so, you can't store it in a session--that's only available to the single user.
I'd use a caching layer like Cache_Lite and cache the result set from the db query based on the query string (not the sql query, but the search parameters from your site). That way identical searches will be cached. Handle the sorting and pagination of the array in PHP, not in the DB.
I am writing an application which shows a user one thing to vote on, at a time. I have a MySQL table which contains these things. Right now I have it set up so that upon login, I query my database to get a limited number of these things, and then I use PHP to turn that into an array. After a user submits a vote, the thing they've already voted on is 'unset' from the array. When the new array size is one, I query my database to create a new array.
Is this a 'bad' way to do it? Should I instead just query my database to get a new thing for the user to vote on after every time they submit a vote?
Any help/suggestions appreciated.
This will likely get closed because it's subjective...
IMHO, it's all a matter of how you want it to function. Typically, in standard programming, I suggest loading everything up-front so that once loaded, the user's experience is very smooth and without loading.
In Web programming, however, using AJAX or something similarly asynchronous to dynamically modify/rebuild the array as you need is certainly acceptable, especially if the end result is functioning in a way you're happy with.
Bottom line: Either way will work - it depends on your needs.
Reducing database interactions will typically make your web app perform better. If performance is ever going to be a concern, this could help there. On the other hand it makes the code a bit more complicated, which could impact maintainability in the future.
In the end, it's a trade off. As long as everything is done in a clear and logical way, either approach should be ok.
I have a sort of vague question that you guys are perfect for answering. I've many times come across a point where I've had a form for my user to fill out where it consisted of many different pages. So far, I've been saving them in a session, but I'm a little worried about that practice since a session could expire and it seems a rather volatile way of doing it.
I could see, for example, having a table for temporary forms in SQL that you save to at the end of each page. I could see posting all the data taken so far to the next page. Things along those lines. How do you guys do it? What's good practice for these situations?
Yes, you can definitely save the intermediate data in the database, and then flip some bit to indicate that the record is finished when the user submits the final result. Depending on how you are splitting up the data collection, each page may be creating a row in a different table (with some key tying them together).
You may also want to consider saving the data in a more free-form manner, such as XML in a single column. This will allow you to maintain complex data structures in a simple data schema, but it will make querying the data difficult (unless your database supports xml column types, which most modern enterprisey databases do).
Another advantage to storing the interim data in the database is that the user can return to it later if he wishes. Just send the user an email when he starts, with a link to his work item. Of course, you may need to add whatever security layers on top of that to make sure someone else doesn't return to his work item.
Storing the interim data in the DB also allows the user to skip around from one page to another, and revisit past pages.
Hidden fields are also a good approach, but they will not allow the user to return later.
I would avoid storing large data structures in session, since if the user doesn't invalidate the session explicitly, and if you don't have a good mechanism for cleaning up old sessions, these expired sessions may stick around for a long time.
In the end, it really depends on your specific business needs, but hopefully this gives you something to think about.
I would stick with keeping the data in the session as it is more or less temporary at this stage: What would you do if a user does not complete the forms? You would have to check the SQL table for uncompleted data regularly making your whole application more complex.
By the way, there is a reason for session expiring namely security. And you can define yourself when the session expires.
Why not just pass things along in hidden parameters?
Ahh, good question.
I've found that a great way to handle this (if it's linear). The following will work especially well if you are including different content (pages) into one PHP page (MVC, for example). However, if you need to go from URL to URL, it can be difficult, because you cannot POST across a redirect (well, you can, but no browsers support it).
You can fill in the details.
$data = array();
//or//
$data = unserialize(base64_decode($_POST['data']));
// add keys to data
// serialize
$data = base64_encode(serialize($data));
<input type="hidden" name="data" value="<?= htmlspecialchars($data, ENT_QUOTES); ?>" />
This answer is based on this answer.
Cha uses arrays in storing login -info in contrast to my code.
It likely improves the efficiency in searching the login -data and keeps your data organized.
However, I am not sure whether this is the best data structure in storing all pieces of the login info.
My solution always fetches passhash from the database when needing the info and then destroyes it after the use, instead of storing it to the array in PHP for session. It also keeps all variables as independent variables. It uses heavily PostgreSQL in contrast of data manipulation by a scripting language.
Which are the pros and cons of using arrays in PHP for storing login data?
[edit]
I use the following code at the moment in getting the data from the database.
$result = pg_prepare($dbconn, "query22", "SELECT passhash_md5 FROM users
WHERE email=$1;");
$passhash_md5 = pg_execute($dbconn, "query22", array($_REQUEST['email']));
So it should be changed to PDO to make it better. Studying that.
The Pros of keeping data using a Session based login system is the fact that it doesn't hit the database very hard. Databases are a single entity, as in you connect to the database and a table. If you have millions of pages doing that, things can get tricky.
On the other hand, storing stuff in a session array, you have a lot of small files that are each their own separate entity, and each is only accessed once per page view by that specific visitor.
Session files also are smaller and easier to grab everytime. In a database, you have to search through a lot of records (if you have a lot of users), and find the specific record. In contrast, sessions simply grab the data in a specific file for that specific session.
Going from what Ryeguy added. I would highly advise against select every record, and then doing a while loop through them to find the right user. I'd suggest look at the Where statement, so you can have the database only give you the record that matches the user's username.
That was just a matter of preference, it really doesn't matter. One possible use is a sort of namespacing, though. Imagine you have two forms on one page: login and register. Obviously, at the very least, these forms would both have a username and password field. To differentiate between the two, you could have the fields named register[username] and login[username] (ditto with password), that way you could tell which is which.
Also, please don't use the SQL query in your other question. Do you realize you're returning the ENTIRE user table every time someone logs in? Imagine what happens if you get 100,000 users on your site..your logins would take minutes and your database would be brought to its knees. I think you should learn some basic sql before tackling this.
Also, look into using PDO instead of the procedural database functions. PDO is cleaner, easier, and can be faster in some cases.