Let me start with a simple example to show how my data is structured. There are four tables, Employee, Store, Department, and Employee_Department_Permissions.
Departments belong to Stores (for example, the Department table might contain a record for the dairy department of store 5). Employees are given the right to work in Departments through the Employee_Department_Permissions table, which contains the Employee id and Department id.
Let's say an employee can log in to my application and view a list of every store in the database. Next to each store, I want to print out how many departments they can work in at each store. I have an Employee model with a mapper that provides the fetchAll method to accomplish the first part.
But, where should I find out how many departments an employee can work in? In my model wrapper, I can call findDependentRows to do this. Or, I could do it in my controller with raw Zend_Db_Select calls. A third option I was considering would to be just add a column to the Employee table that holds this information, but then I'd need to update a second table when Employee_Department_Permission is modified.
Thank you in advance for any advice.
As a very general rule of thumb, I would suggest you try keep the controller as free as possible from fetching information for the views. This is a task best handled in the model.
Sure it's easy to just fetch from controller, I mean, since we are there processing a request, it would be so simple to just do a quick fetch and push that off to the view. This is where dicipline comes into play. As your application grows you will appreciate having the clean separation this methodology offers you if applied.
My 2 cents, happy coding to you friend.
Related
Heya I am novice web dev or actually I am still in education.
I got this situation Where I have 3 tables lets say : Students, Groups and a join table Student_group.
I put my data from Students in the student model and from groups I put its data in the Group Model so I can use it my application. But I store a date in the Student_group table because I need to know when a student changed from a group.
So my question is in which model do I put this date? Do i need to make a new model for the combined tables or do I need to add another attribute to the student model?
Thanks in advance ;D
That depends. Will the student be in many groups, or one?
If one (one to one relationship), you can decide where to put it. The column could be in either the Student table, or the Student_group. In this case, though, it may be advisable to flatten the data and simply add group columns in your Student table. You decide that as well - if it seems unnecessary to have a join for a one to one relationship (usually it is, not always), then flatten it. In either case, the data should stay in its respective model. That said, you should use the Student model if you handle it in the Student table.
If many (one to many relationship), I'd advise putting it in the Student_group table and leaving it in that model as well.
All in all, the model should be a direct reflection of the data it's representing. You could make some methods inside your Student model to make it easier to get the date, for example. However, I'd personally handle that date inside of the proper model, Student_group. As mentioned, the model should be a direct representation of the data. Again, though, there's nothing wrong with making things a bit easier by creating some methods that help out the developer.
I have a general question about how to implement the best practice of model structure for an application I'm building in Laravel 5.
So, at the moment I have things set up like this:
'user' model and table: id, email, password, admin level - this is really just the info for authenticating login.
'user-details' model and table: id, userID (foreign key for user table id field), name, address etc - all the other details
'lesson-type' model and table: id, teacherID (foreign key for user-details table id field), lesson-label etc - info about different types of lessons
At the moment I have a Teacher Controller in which I'm passing through to the view:
- The info from the User table
- The info from the User-details table
- A list of different lesson types for the teacher from the Lesson-type table
But I kind of feel that all this should be tied together with one separate Teacher model which would extend the User-details model (and probably which in turn should extend the User model), but wouldn't have it's own table associated with it, but all the info pertaining to either updates for the User-details or the Lesson-types table would be stored in those relevant tables. Would this be correct?
(I should also say that users may alternatively be parents rather than teachers, and so would I would have a separate Parents model for all the properties and so on associated with parents)
I would then pass only the Teacher model object into the view and thus gain access to all the teacher info such as personal details and array of lesson types.
As I'm typing, this is sounding more and more to me like the right way to go, but it would be great to get some advice.
1 - technical implementation: I guess in the Teacher model, I'd populate all the relevant teacher into class variables (Name, array of lessons etc) in the constructor?
2 - am I over complicating this structure by having both Users AND Users details tables?
3 - Does what I'm proposing make the most structural sense in Laravel?
4 - just another thought I've just had, should the teacherID in the lesson-type table actually refer to the User table rather than the User-detail table... so user-detail and lesson-type would both be direct children of the user table??
Very much obliged for any help :)
You shouldn't extend models like that unless there is a clear inheritance. From a logical standpoint, it just doesn't make any sense since you'll have to overwrite most of what is on the User model anyway. And what you don't overwrite will be incorrectly mapped to the database because they are 2 completely different tables. What you actually want to do is utilize Eloquent relationships.
For clarity, I am assuming this basic structure:
users - id
teachers - id, user_id
user_details - id, user_id
lesson_types - id, teacher_id
Those should be 4 completely different models all interconnected using the Model::belongsTo() method. So the Teacher model would be
class Teacher extends Model {
public $table = 'teachers';
public function user() {
return $this->belongsTo('App\User');
}
}
When you query for a teacher, you can do Teacher::with('user')->get(). That will return all records from the teachers table and on each instance of the Teacher model, you'll be able to call $teacher->user and get the User instance associated with that teacher. That is a full model, not just extra data, so you have access to everything on the User Model, which is generally the main reason for extending
For your list of questions:
I may be misunderstanding you, but this isn't how an ORM works. I'd suggest going back and reading through the Eloquent docs (if you're running 5.0, I suggest reading 5.1's docs since they are much, much better)
It will depend on who you ask, but I tend to think so. If the data is clearly related and there is no reason for it to be shared across record types (for example, I generally have an addresses table that all records reference instead of having 5 address fields repeated on multiple tables), I believe it should all be on one table. It just makes it more difficult to manage later on if you have it in separate tables.
There will be those who disagree and think that smaller scopes for each table are better and it will likely allow for quicker queries on extremely large datasets, but I don't think it's worth the extra trouble in the end
No, as I have explained above
The teacher_id column should reference the teachers table, assuming that lessons belong to teachers and cannot belong to just any user in the system. Using the ORM, you'll be able to do $lesson->teacher->user->userDetails to get that data
I really think you need to go back and read through the Eloquent docs. Your understanding of how Eloquent works and how it is meant to be used seems very basic and you are missing much of the finer details.
Basics
Relationships
Laracasts - Laravel Fundamentals - You would benefit from watching Lesses 7-9, 11, 14, and 21
I'm trying to get used to relational active record but things look too complicated for now.
If it's not difficult please point me in right direction.
I have 4 tables.
Users
userID[pk],userName
Cars
car_id[pk],userID[fk to Users],car_nickname,make_id[fk to Makes],model_id[fk to Models]
Makes
make_id[pk],make_name
Models
model_id[pk],model_name,make_id[fk to Makes]
Now input data is userName,make_name,model_name and task is to get car_nickname from Cars table.
Is this possible using relations or should I do it step by step checking makes,models,users for IDs and then puting all IDs into Cars to get car_nickname ?
You can yous only one Model with reliations to all tables. And create one _form.php in the Views, where there will only fields you need.
Some halpfull information. if you save some data into some table and you need saved data id, you caN use $newid = $model->getPrimaryKey(); and assign to new variable , wich will save into other tables.
I think this is short way to solve problem
I am designing a database for a system that will handle subscription based products, standard one off set price purchase products, and billing of variable services.
A customer can be related to many domains and a domain may have many subscriptions, set priced products or billed variable services related to it.
I am unsure whether to seperate each of these categories into their own 'orders' table or figure out a solution to compile them all into a single orders table.
Certain information about subscriptions is required such as start date or expiry date which is irrelevant for stand alone products. Variable services could be any price so having a single products table would mean I would have to add a new product which may be never used again or might be at a different cost.
What would be the best way to tackle this, and is splitting each into seperate order tables the best way?
Have you looked at sub-typing - it might work for you. By this I mean a central "order" table containing the common attributes and optional "is a"/one-to-one relationships to specific order tables. The specific order tables contain the attributes specific only to that type of order, and a foreign key back to the central order table.
This is one way of trying to get the best of "both" worlds, by which I mean (a) the appropriate level of centralisation for reporting on things common and (b) the right level of specialisation. The added nuance comes at the cost of an extra join some times but gives you flexibility and reporting.
Although I am a little biased in favour of subtypes, some people feel that unless your order subtypes are very different, it may not be worth the effort of separating them out. There is some seemingly good discussion here on dba.stackexchange as well as here. That being said, books (or chapters at least) have been written on the subject!
As with any data model, the "best" way depends on your needs. Since you don't specify a lot of details regarding your specific needs, it's difficult to say what the bets model is.
However, in general you need to consider what level of detail is necessary. For example if all subscriptions cost the same and are billed on the 1st of the month, it may be sufficient to have a field like is_subscription ENUM ('Y', 'N') in your orders table. If billing dates and prices for subscriptions can vary however, you need to store that information too. In that case it may be better to have a separate table for subscriptions.
Another consideration is exactly what an "order" represents in your model. One interpretation is that an order includes all the purchases included in one transaction, including both one-off purchases, variable services and subscriptions. A completed order would then result in a bill, and subscriptions would be automatically billed on the proper day of the month without a new order being made.
You should aim to have one database design that is not hardwired into specifics regarding its contents, and if it does (have to) it does in such a way that it seperates the specialization from the core DB design.
There are certain fields that are common for each order. Put these in one table, and have it refer to the other rows in the respective (specialized) tables. Thats DB normalization for you.
You could have main table contain ID, OrderID, ItemType, ItemID when ItemType determines the table ItemID refers to. I advise against this, but must admit that i use this sometimes.
Better would be to have these tables:
Clients: ID, Name, Address, Phone
Sellers: ID, Name, CompanyAlias
Orders: ID, ClientID, SellerID, Date, Price
OrderItems: ID, OrderID, DiscountAmount, DiscountPercentage,
ProductDomainID, ProductBottleID, ProductCheeseID, ..
Now OrderItems is where the magic happens. The first four fields explain themselves i guess. And the rest refers to a table which you do not alter or delete anything ever:
Products_Cheese ID, ProductCode, ProductName, Price
And if you do need a variant product for a specific order add a field VariantOfID thats otherwise NULL. Then refer to that ID.
The OrderItems table you can add fields to without disturbing the established DB structure. Just constrict yourself to use NULL values in all Product*ID fields except one. But taking this further, you might even have scenario's where you want to combine two or more fields. For example adding a ExtraSubscriptionTimespanID or a ExtraServicelevelagreementID field that is set alongside the ProductCheeseID.
This way if you use ProductCheeseID + ExtraSubscriptionTimespanID + ExtraServicelevelagreementID a customer can order a Cheese subscription with SLA, and your database structure does not repeat itself.
This basic design is open to alterative ideas and solutions. But keep your structure seperated. Dont make one huge table that includes all fields you may ever need, things will break horribly once you have to change something later on.
When designing database tables, you want to focus on what an entity represents and having two or more slightly different versions of what is essentially the same entity makes the schema harder to maintain. Orders are orders, they're just different order types for different products, for different customers. You'd need a number of link tables to make it all work, but you'd have to make those associations somehow and it beats having different entity types. How about this for a very rough starting point?
What would be the best way to tackle this, and is splitting each into seperate order tables the best way?
That depends. And it will change over time. So the crucial part here is that you create a model of the orders and you separate the storage of them from just writing code dealing with those models.
That done, you can develop and change the database structure over time to store and query all the information you need to store and you need to query.
This for the general advice.
More concrete you still have to map the model onto a data-structure. There are many ways on how to solve that, e.g. a single table of which not all columns are used all the time (flat table), subtype tables (for each type a new table is used) or main table with the common fields and subtype tables containing the additional columns or even attribute tables. All these approaches have pros and cons, an answer here on Stackoverflow is most likely the wrong place to discuss these in full. However, you can find an insightful entry-level discussion of your problem here:
Entity-Attribute-Value (Chapter 6); page 61 in SQL Antipatterns - Avoiding the Pitfalls of Database Programming by Bill Karwin.
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.