views:

49

answers:

2

I'm having a bit of trouble figuring out what would be the best approach for creating the database tables for the following (rather complex) data structure and I'm hoping that someone with more experience than me could help out. The main reason for my trouble is both normalization and trying at all costs to avoid querying inside loops.

location 1 (location_group_name, owner_id, admin_id)
  location 1.1 (name, address)
     location 1.1.1 (name)
        // DEVICE LIST
        device 1 (manufacturer_id, model_id, serial, purchase_date, service_date)
            Battery (manufacturer_id, model_id, purchase_date, service_date)
            Accesory 1 (manufacturer_id, model_id, purchase_date, service_date)
            Accesory 2 (...)
            Accesory n (...)
        device 2
            Battery
            Accesory 1
            Accesory 2
            Accesory n
        device n

        // STAFF LIST
        person 1 (name, email)
           qualification 1 (type, date)
           qualification 2 (...)
           qualification n (...)
        person 2
        person n
     location 1.1.2
     location 1.1.n
  location 1.2
  location 1.n
location 2
location n

I am currently thinking of inserting each device and person as a serialized multi-dimensional array, but I am not sure how well that will work due to the fact that a cron job script will check the service_date field every day and send automated emails to the admins and owners of the location groups if certain criterias are met. To complicate things further, the devices data should be searchable by model as well, in case of a recall, or by serial_number for quick find in case the user has lots of devices added and/or doesn't exactly know its location.

If it's not too much to ask, I would also like to see a query example for the proposed data structure (only because I figure it would probably use joins and I am quite unfamiliar with them).

Also if there is any extra info you need, please feel free to ask and I will gladly elaborate.

Thank you in advance, any input will be more than appreciated !

A: 

Looks like you have a one to many relationship between location1.1.1 and device, and between location1.1.1 and person. I think you'll end up querying in a loop, or you're going to do a few large queries and loop to merge them together.

Don't freak out about querying in loops. With prepared statements they don't have to be that slow.

Scott Saunders
+2  A: 

I'm not entirely sure what you're trying to do here, but why all the hierarchy? This is some sort of store/device/employee model, correct? In a relational database, you can separate discrete information into their own sections and relate them on other tables. So if you have stores/devices/employees, you can have a "stores" table, a "devices" table, an "owners" table, an "employees" table, a "stores_employees" table, an "owners_stores" table, a "devices_stores" table (and you could track inventory in that), an "employees_qualifications" table, and so on..

treeface
+1 Agreed, and `JOIN` s solve all possible queries here as far as I can see. But since store->employee is one->many, you wouldn't need to make extra messes like `stores_employees`. If you (@FreekOne) would like, I can sketch it out using Dia and include some example queries...
MvanGeest
Oh, and please excuse me if I'm completely misunderstanding the problem, which is always a possibility...
MvanGeest
+1 from me too, as stated in my question, I did figure as much that JOINs would be needed and that is what I was looking for, the only problem was that I have never done something as complex as this and I didn't really know where to start. The hierarchy actually shows how the info would be presented on the front-end, which is actually very important due to the sheer amount of data that would potentially be displayed. MvanGeest: if you could do that, I would be more than grateful !
FreekOne
My only concern is if some strange relationship arises where an employee works at two stores concurrently or switches stores. In either case, the stores_employees table would become a many-many. Better to code for flexibility now than have to rewrite everything later. I speak from recent experience regarding a major conversion of this sort of thing. Anyway..thanks for the comment.
treeface
@treeface thank you for the heads up, but it won't be the case. The whole application is a bit more complex and didn't really make the objective of my question. Only this is the part that gave me headaches so if I get this nailed down, the rest won't be a problem.
FreekOne
Hmm, I might understand what you mean - to produce that hierarchical layout, you might need querying in loops (first you'd get "Which locations are there in 1?", then "Which locations are there in 1.1?" etc.) I think that's pretty much inevitable - you *can* get all the info from the database at the same time, but then it is not suitable for displaying the way you want to. Let me see (I'll be using MySQL Workbench, as it's just a *little* bit more user-friendly than Dia).
MvanGeest
Well, here you go: http://img835.imageshack.us/i/devicemodel.png/ MySQL Workbench can even create a complete SQL file from this diagram and get your database up and running (actually, it can connect to the server and do it for you!) If you'd like to receive the SQL or the Workbench project (you'll want to make some adjustments), please contact me via my website.
MvanGeest
@MvanGeest: thank you very much, that is what I was looking for ! If you want to post it as an answer along with an example query, I will happily accept it. The key will be the admin_id because the locations are user created so a user can only see his/her own locations.
FreekOne
That's problematic, since there's no table for users (admin_id is a dummy and doesn't have a foreign key constraint yet); should I add one? And what should the query do? (Oh, and the creation SQL is currently about 200 lines.)
MvanGeest
I only need an example because I'm not familiar with JOINs at all. Don't mind the users table nor db creation script (because this is a very simplified version of what the final one would be anyways). What I'm looking for is more of a proof of concept than an exact solution. So, based on your proposed structure, how would I write the query for selecting all the 1st level locations along all their sublocations, devices and staff, for any given admin_id ? Preferable output would be a multi-dimensional array, with similar hierarchy to what I've posted for the ease of iterating through it.
FreekOne
Hey Freek,A join is simply a connection of two tables on a particular pivot point. Let's say you have a "stores" table with store name, id, address, etc., and an "employees" table with employee name, store_id, etc. If you want a result set with employee name and store name you'd do: "SELECT e.*, s.* FROM employees e LEFT JOIN stores s ON e.store_id=s.store_id". So you're basically saying that "store_id" is the place where you want them to connect.
treeface
I'm sorry for the late acceptance. MvanGeest's image helped me the most but since he didn't post it as a separate answer, I will accept yours, with an equally huge 'THANKS' to both of you for the extra help provided in this comments area !
FreekOne