PHP SQL: Dynamically Creating and Deleting Columns in Database - php

I'm creating a carousel/image slider plugin for WordPress and I've hit a wall. There's going to be an indefinite amount of user input and I need to know how to handle this.
I currently have six static inputs: transition_time, loop_carousel, stop_on_hover, reverse_order, navigation_arrows, and show_pagination and the variable amount of info will come from the images the user wants to use. So this could be anywhere from zero to infinite.
I want to be able to create/delete X amount of columns in the DB.
So starting out there will be zero images, meaning six columns. If a user adds two images I want to have eight columns, two created. If the user deletes them then I want to go back to my original six.
I'm guessing this is possible but how and is this a good idea or should I just have a set amount of images?

You Are Doing It Wrong™.
Changing a table definition should be an exceptional event.
Use two tables, one to model the Carousel, one to store image information, then link them.
Table Carousel:
id
[more fields here]
Table Image:
id
carousel_id (reference to the containing Carrousel)
[more fields]

Related

MySQL - Full vs partial row retrieval

I'm programming a website using PHP/MySql to allow visitors to search for real estate listings.
The main page shows the list of advertised apartments, displaying just a small subset of all the available attributes included in the MySql table that contains the apartments listed. The full set of attributes for each apartment is only shown on a secondary webpage, once the user selects a result from the list in the main page. So, if for example, the available features included in the database's table are price, location, number of rooms and surface area, the main page only displays price and location in the results list, and the remaining attributes are displayed only when the user selects a specific result from the list.
I'm wondering what is the best strategy in order to ensure fast response from the database and achieve the highest possible amount of concurrent users: Should I retrieve ALL the columns from the table when showing the full result list of results and avoid querying the database when the user selects a given result (since I already have all the data I need to show), or should I only extract the minimum amount of columns to display in the results list (price and location, following the example above), and fetch the remaining columns for a specific record only when the user selects a specific result?
I'm querying a single table (no joins or complex queries, although I do use a where clause) and the results list is expected to show around 30 to 50 records at a time. I don't have any data regarding how many of the results in the list shown are selected by the user to see additional info, but I would say it's resonable to say that it will select around 60% of them.
Thanks in advance for your help!
I'd fetch the first few rows and then use endless scrolling techniques via ajax. Be sure to have a (sometimes a little outdated) static list of all entries (meaning: cache them) linked to from every page. That way Google can reference every "sigle view object pages".

What is the best way to handle large recursive queries in mysql?

Using PHP & Mysql-
I have a list of 120,000 employees. Each has a supervisor field with the supervisor employee number.
I am looking to build something that shows the employees in a tree like format. Given that if you click on anyone that you have an option to download all of the employees (with their info) that are under them.
So two questions - should I write my script to handle the query (which I have but is SLOW) or should create some sort of helper table/view? I am looking for best practice behind this.
Also I am sure this has been done a million times. Is there a good class that handles organization hierarchy?
The standard way of doing this is to use one table to store all of the employees, with a primary key field for the employee_id, and a field for supervisor_id which is a 'self join' - meaning that the value in this field points back to the employee id of this employee's supervisor. As far as displaying the employee tree - for relatively small trees, the entire tree structure can be sent to the client's browser when the page is created, and tree nodes can be displayed as the nodes are clicked from the stored data. But, for larger trees, it is better to fetch the data as needed, i.e. when the nodes are clicked. If you have 120,000 employees, then you might want to use the later approach.

PHP/MYSQL store variables in array or separate fields

Premature optimization is the root of all evil...but...
I am allowing users to input data within categories as in favorite players, favorite teams etc. They can then use these choices to filter results. I let them input lists separated by commas so after exploding the data I have it in an array. So how to store.
Method 1: I could create a table of users, one row per user, with the categories, as in players, teams as fields and save the choices of each users as an array in the respective field. (userid would link to basic users table.)
Method 2. Or I could create separate tables for each thing, players, teams, etc, and have a fixed number of fields say 10, break up the array into each individual value, store and place it in its own field. (Already have this code working.) (Again userid is primary key.)
The advantage of Method 1 is it's a bit simpler, one table, no limit on number of choices.
Method 2 seems a bit more robust. The data is more visible and possibly easier to get and retrieve--although maybe not.
Does anyone have experience with this sort of thing and could recommend one over another?
Thanks for any recommendations, suggestions!

how to add/edit/manage related data in multiple tables

I have several tables that i need to create an admin interface for
Table 1
Table 2
Table 3
Table 4
Table 5
each table's contents are reflected of which parent it belongs to in a field...so
table 2, has a field for which row in table 1 it relates to, table 3 has a field for relating to table 2 and so on.
Whats the best way to present this to the user so they dont have to memorize id numbers. Say for instance, they want to add a new entry in table 3, they must select which row in table 2 to link to.
The relationship only extends one level above after table 1. So creating a new set of options in table 5, would involve creating an entry in table 1, new entry in table 2, linking it to table 1, new entry in table 3, linking it to table 2, new entry in table 4, linking it to 3, and finally the new option in table 5.
So my question is user-interface related as to the best way to present this to the user. Alternatively, what is this kind of system called, so i can search for other examples.
Thanks.
From what you're saying, it looks like it's not possible for one entry in a table to exist without the corresponding entries in the other tables, right?
In that case, you could present a wizard like interface which prompts the user to enter the data for each table on each new wizard page, starting from the data for table 1. Then once all the data has been collected, you can fire off a series of update statements where the id of the record in table 1 is reused for the inserts in tables 2-5. (Depending on your table design, you might get this id using LAST_INSERT_ID()).
Or if you don't want to use multiple insert statements, you might use an updateable view (if you're using MySQL 5).
Alternatively, you could have a table structure where a record in table X must have a linked record in table Y (where Y < X). In other words, a record in table 1 may not have a linked record in table 2, but a record in table 2 must have a linked record in table 1.
In this case, you can still use the wizard, but you can start with the table that you actually want to create information for, then have the wizard prompt for data for the previous table, and so on until it prompts for data for table 1. So if you really want data to be created for table 4, have the wizard prompt for that first, then prompt for data for table 3, and so on up to table 1. Then do the data entry as before.
Sounds like a problem ready-made for my old favorite, the master-detail layout. Each table is represented in a separate pane (Panes 1 through 5) displayed in the same window. The panes are arranged top-to-bottom and/or left-to-right for Tables 1 through 5 sequentially. In each pane, there is always exactly one “active” record, which is marked for the user in some way. The contents of each pane are determined by the active records in the panes above/left of it. Thus, Pane N shows the Table N records for the active record of Table N-1 shown in Pane N-1. The active record in a pane is whichever record in the table last had focus (in any field). Thus, for example, the user can display the Table N records for a particular record in Table N-1 by clicking on any field for that record in Pane N-1. Queries for Pane N are launched asynchronously once the active record changes in Pane N-1 (no “Refresh” button, please). All non-read-only fields should be edit-in-place. A Save button or menu item inserts/updates all records of all tables as a batch (alternatively, you can fire an Update whenever a field is edited and focus leaves it, if your bandwidth can handle it).
Thus, to add a new record to Table N, the user places focus on the correct records for Table 1 through Table N-1, then places focus in Pane N (e.g., click anywhere in it) and selects the Add Record menu item. This inserts a new blank record in Pane N for the user to complete. The user can continue to select Add Record to fill Pane N with the desire records for the active Table N-1 record. At any time, the user can use the same process to add Table N+1 records for a newly created Table N record by clicking on Pane N+1 and selecting Add Record. Also, at any time, the user can edit the fields of the records in any pane. (Alternatively, you can have separate Add Record menu items for each table, which saves the user having to shift focus to a pane to add records, but that many menu items can get more cluttering than its worth; another approach is to always have a blank record in each pane ready for the user to fill out, eliminating the need for the Add Record menu item).
This design provides the users with the most flexibility, allowing them to add, delete, and update records in any order convenient for any table at any time. Because the window “remembers” the active records between edits, it’s also very efficient, eliminating the tedious re-selecting of Table 1 through N-1 records to edit a series of Table N records for a particular Table N-1 record (unlike, say, a wizard). It displays all the records for all tables in a single window in an intuitive hierarchical layout that facilitates viewing and exploring the data and minimizes navigation among windows or pages (again, unlike a wizard).
Five panes is a lot for a single window, but not too much. However, it would help if you provided easy ways for users to resize and hide/show each pane. Thus, if the user needs to work on a bunch of Table N records of a record in Table N-1, she or he can hide all the other panes, expanding Pane N to full window size to minimize scrolling. Also, if the user does not ever need to study or edit the records of some of your tables, do not put them in panes of their own, but rather make each appear as a field for the adjacent table in the structure. For example, if the users aren’t allowed to edit Table N, then instead of Pane N you can have a field in Pane N+1 that displays the functional name of the Table N record that each Table N+1 record belongs to. By making it a drop-down list, user will be able to assign/re-assign the Table N record for any Table N+1 record.
Details at http://www.zuschlogin.com/?p=31.
More stuff at Stack Overflow than may be relevant:
Hierarchy Visual Design
UI design pattern for multi level grid
What’s best when inserting into a table view, and add button or a blank line?

How should I store product and product image data for an online store?

I'm working on a storefront application in PHP with MySQL. I'm currently storing my data in 4 tables: one for product lines, one for specific products within those product lines, one for product images, and one which specifies which images are linked to which specific products. Each specific product belongs to one product line, each product image can belong to several specific products, and each specific product can have several images. My tables look like this:
ProductLines
id, name, description, etc.
SpecificProducts
productLineID
id, color, size, etc.
ProductImageLinks
specificProductID
imageID
Images
id, imageFileLocation, name, etc.
It's working fine this way, but it seems like it's not very efficient for retrieval purposes.
For example, I have a page that lists each product line along with a thumbnail of a randomly chosen image from that product line. To do that I have to first query the database for a list of all product lines, then perform a separate query for each product line to get all of the specific products that have associated images, pick one of those, and then query again to get the image.
Another possibility I considered would be to use one query to get all the product lines I'm looking at, a second query to get all the specific products for all of those product lines, a third query to get all of the image links which specify which images are linked to which specific products, and a fourth query to get all those images. I imagine this would be a bit faster because of the reduced number of queries, but it would leave a lot of work for PHP to do figuring out the connections between product lines and products and images, which could be just as slow.
So my question is, is there a better way to store this data? Or a better way to retrieve it based on the database I already have in place? Or is one of the two options I've identified really my best bet?
Edit: I'm not actually storing image files in the database. The image files are stored in the file system. My "Images" table in the database just stores the location of the image file along with useful info like the image title, alt text, etc.
Yes - just write a single query that will retrieve all that information in one shot.
I'm a little rusty on this, but you can lookup the queries in mysql reference.
create a query that joins these tables on the appropriate keys
you need to select the first item from a subquery that retrieves the images for a specific query, and then order by rand() and select the first.
This can definitely be done in a single query. Even if it can't you can always create views which is sometimes a better way to organize your queries so that they are more readable. In other words, instead of returning the result of your query, just create a view corresponding to your first query. Then create a view that corresponds to running your second query on the result of the first query, that operates off the view. And so on. Then, your actually query can be done in one shot by retrieving from the final view.
As far the database design goes, you have a fairly solid (and standard) design. You could combine your ProductImageLinks and Images tables as long as it's a 1:1 relationship to save some queries.
As for your product line image retrieval, you have a couple of options that would drastically reduce the number of queries required:
Create a new table in your database called ProductLineImages. Instead of picking the image randomly from the associated products, load a set of images in there that you can choose randomly from. It won't be as dynamic this way, but this is the most efficient method.
You can do all of what you described in a single (but less efficient than #1) query.
Are you set on storing the images in the mysql database?
In my, similar application, I simply stored the images in /images/productimages/imagesize/productid.jpg where imagesize is "small", "large" etc, for different thumbnail sizes, and productid.jpg is the id from the SpecificProducts table

Categories