I am designing a database for use with CakePHP 3, but I am having trouble figuring out how to set up and define a particular relationship.
I have 'Contracts' which can have multiple 'Properties', but each Contract<->Property relationship can have multiple 'ContractEvents'. Normally I would join the 'contract_events' table to the 'contracts_properties' table but I can't seem to figure out how to get CakePHP to recognise this or whether this is the correct convention.
Here is a diagram trying to illustrate what I want:
Contracts <- Join Table -> Properties
|
v
ContractEvents
Apologies if this is unclear or a dupe, I wasn't really sure how to phrase it when searching. Please let me know if you need anymore information.
Thanks
Related
i wanted to get your expert opinion about this dilema chosing bewteen JSON or Pivot Table
Let just say we have 2 tables here
people
jobs
A person may have multiple jobs, alas, a jobs might have multiple person subscirbed to it.
What is the best approach to it?
Method 1: JSON
I would have jobs column in people table, that contain json array of that person's jobs id, example : [1,2,4]
Method 2: Pivot
I would create pivot table job_person with job_id and person_id column, well, you know Laravel Eloquent style many to many pivot table
I have done some searching, and i found articels favouring each method, some say JSON better because it musch simpler, others would say Pivot is better due to that is how relationship database should work, etc etc.
But i want to know, which one should i use in what scenario? Like if it is just simple case like above scenario, JSON would be better?
What if there are other variables included like additional pivot columns
(Maybe each pivot also contain status column that can be set to active or past_job)
Or what if in the future we want to be able to get all peoples whom have a specific jobs, in which case Pivot would be preferable i think.
What if instead of jobs, the other table would be books and a person can have an extensive of books making we might have tens, or even hundreed pivot records just for one person? And there will be another hundreed persons?
What if instead of books, the other table were stocks in which case, a person might subscribed / unsubscribed multiple stock multiple times?
And maybe to the basic principle, what is each one's advantages/disadvantages?
Thank you very much
I would rather not choose JSON, as there's no benefit from choosing it, you will sacrifice many of the database features and make querying the data difficult and slow.
What if there are other variables included like additional pivot
columns (Maybe each pivot also contain status column that can be set
to active or past_job)
Job and Person are not dependent on each others, so you need to create an associative table between them something like "PersonJob" and add necessary information to it, this is easy to traverse in Laravel.
Or what if in the future we want to be able to get all peoples whom
have a specific jobs, in which case Pivot would be preferable i think.
You could easily query this using the associative table.
And maybe to the basic principle, what is each one's
advantages/disadvantages?
it just that relational databases are made for this kind of stuff and JSON offer no value just hardship.
This statement works in SQL, I just cannot figure out how to convert it to django. Im sure it uses prefetch_related, Prefetch, or select_related but im still having a hard time understanding those concepts. I do see that prefetch basically has to have the field under that table.
My goal: Not all brands have products. All products have brands. Show my only brands with products. I was hoping to implement Brand.objects.[insert-filter-here]
Model.py (appended version of actual models.py file)
class Product(models.Model):
brand = models.ForeignKey(Brand)
class Brand(models.Model):
name = models.CharField
SQL
SELECT DISTINCT products_brand.name FROM produts_brand INNER JOIN products_product on products_brand.id=products_product.brand_id;
Its 2 tables becuase the products table has many many columns (27), I guess the other option is to just
combine them. But I wanted more control over Brand objects for ease of lookup/editing.
Many thanks for your help!
It should just be Brand.objects.filter(product__isnull=False).distinct(). You can follow the foreign key relation backwards using the default reverse name (or a different one if you used the related_query_name field argument to specify one when declaring your ForeignKeyField).
Without the distinct() you may get duplicate entries.
See the "Lookups that span relationships" docs for more details and examples.
Thanks guys! I failed to mention i was using MYSQL backend and not SQLite but Peters answer got me in the right direction though, I got.
Brand.objects.values('name').distinct().filter(products__isnull=False)
This is a little difficult for me to explain but I will try my best to explain to you guys in short. Iam designing a search engine for a relational database. I want this to be independant of the structure of the database i.e it can run on any database provided. I want that when the user inserts a string such as two names 'abc xyz' ,it displays all the rows containing both the names 'abc xyz' in them and if there are no such rows then it should display rows with name 'abc' and rows with name 'xyz' and show the relationship between the two. For example 'abc' is friends with 'mno' which in turn is friends with 'jkf' which in turn is friends with 'xyz'. So i want to show this relationship as well.This is just an example of the thing i want my application to do. I want it to search all such relationships , if they exist and display them. I know this example is a bit vague compared to the complexity of the application but any ideas are appreciated.
Note:
I know about neo4j and orientdb Dbms which uses graph databases but i dont wanna use them. I believe a graphical approach for finding such relationships would be required. But I wanted to ask if such a task can be done using sql only. Iam using mysql as my database. please help me out woth any queries or stored procs which are suitable for my platform. from what ive learnt information_schema can come in handy but i dont know how to use it for this purpose. Also if there are any other languages which can do this job , I would like to hear about them as well.
From my perspective. the traversal of the database from point A to point B (point A nd B are words in the string given by the user) would also help me out. All opinions are fully welcomed.
I'm not sure if i got you right, but I hope this will help you anyway.
If you want to search a relation between two rows over several points it's basically a graph search problem, see also Wikipedia | Graph theory. To explain that a little...
You can visualize the relation between every row as a graph, for example the persons who know each other:
A--B
\ /
C
Now a more complex example:
A--B--D
\ / /
C--E--F
In this case A knows E for example via C but also A knows E via B and D
Also B knows F via D and E or via C and E
This works for all records stored in the same table as well as for records in any other table. To access for example all nodes with a direct relation to your search record in the same table use:
SELECT * FROM TABLE WHERE referenced_rec =
(SELECT rec FROM TABLE WHERE value = "abc")
AND value = "xyz"
To access all records stored in tables directly related to this table:
select * from (
select TABLE_NAME
from INFORMATION_SCHEMA.KEY_COLUMN_USAGE where
REFERENCED_TABLE_NAME = 'your_current_table')
where your_current_table.value = "abc"
AND (select REFERENCED_COLUMN_NAME from INFORMATION_SCHEMA.KEY_COLUMN_USAGE where REFERENCED_TABLE_NAME = 'your_current_table') = (select COLUMN_NAME from INFORMATION_SCHEMA.KEY_COLUMN_USAGE where REFERENCED_TABLE_NAME = 'your_current_table')
AND (select COLUMN_NAME from INFORMATION_SCHEMA.KEY_COLUMN_USAGE where REFERENCED_TABLE_NAME = 'your_current_table') = "xyz"
I'm pretty sure this won't work, but for now I don't have a chance to test. However getting these SQL's right is another topic and you can maybe take a look for this Stack Overflow Question
As soon as you're able to get all the records from this or any related table you can map this to graph as shown above.
You can't solve this using SQL alone as you don't know how many steps will be necessary to resolve it. You can use any shortest way algorithm for this for example a Wikipedia | Djikstra. I suppose you can find information about how to implement this with a short search.
I hope this could help you a little ;-)
Best Regards
Sverre
I have a type of data called a chain. Each chain is made up of a specific sequence of another type of data called a step. So a chain is ultimately made up of multiple steps in a specific order. I'm trying to figure out the best way to set this up in MySQL that will allow me to do the following:
Look up all steps in a chain, and get them in the right order
Look up all chains that contain a step
I'm currently considering the following table set up as the appropriate solution:
TABLE chains
id date_created
TABLE steps
id description
TABLE chains_steps (this would be used for joins)
chain_id step_id step_position
In the table chains_steps, the step_position column would be used to order the steps in a chain correctly. It seems unusual for a JOIN table to contain its own distinct piece of data, such as step_position in this case. But maybe it's not unusual at all and I'm just inexperienced/paranoid.
I don't have much experience in all this so I wanted to get some feedback. Are the three tables I suggested the correct way to do this? Are there any viable alternatives and if so, what are the advantages/drawback?
You're doing it right.
Consider a database containing the Employees and Projects tables, and how you'd want to link them in a many-to-many fashion. You'd probably come up with an Assignments table (or Project_Employees in some naming conventions).
At some point you'd decide you want not only to store each project assignment, but you'd also want to store when the assignment started, and when it finished. The natural place to put that is in the assignment itself; it doesn't make sense to store it either with the project or with the employee.
In further designs you might even find it necessary to store further information about the assignment, for example in an employee review process you may wish to store feedback related to their performance in that project, so you'd make the assignment the "one" end of a relationship with a Review table, which would relate back to Assignments with a FK on assignment_id.
So in short, it's perfectly normal to have a junction table that has its own data.
That looks fine, and it's not unusual for the join table to contain a position/rank field.
Look up all steps in a chain, and get them in the right order
SELECT * FROM chains_steps
LEFT JOIN steps ON steps.id = chains_steps.step_id
WHERE chains_steps.chain_id = ?
ORDER BY chains_steps.step_position ASC
Look up all chains that contain a step
SELECT DISTINCT chain_id FROM chains_steps
LEFT JOIN chains ON chains.id = chains_steps.chain_id
I think that the plan you've outlined is the correct approach. Don't worry too much about the presence of step_position on your mapping table. After all the step_position is a bit of data that is directly related to a step in the context of a chain. So the chains_steps table is the right place for it IMHO.
Some things to think about:
Foreign keys - use 'em!
Unique key on the chains_steps table - can a step be present in more than one position in a single chain? What about in different chains?
Good luck!
I am making a database that is for employee scheduling. I am, for the first time ever, making a relational mySQL database so that I can efficiently manage all of the data. I have been using the mySQL Workbench program to help me visualize how this is going to go. Here is what I have so far:
What I have pictured in my head is that, based on the drawing, I would set the schedule in the schedule table which uses references from the other tables as shown. Then when I need to display this schedule, I would pull everything from the schedule table. Whenever I've worked with a database in the past, it hasn't been of the normalized type, so I would just enter the data into one table and then pull the data out from that one table. Now that I'm tackling a much larger project I am sure that having all of the tables split (normalized) like this is the way to go, but I'm having trouble seeing how everything comes together in the end. I have a feeling it doesn't work the way I have it pictured, #grossvogel pointed out what I believe to be something critical to making this all work and that is to use the join function to pull the data.
The reason I started with a relational database was so that if I made a change to (for example) the shift table and instead of record 1 being "AM" I wanted it to be "Morning", it would then automatically change the relevant sections through the cascade option.
The reason I'm posting this here is because I am hoping someone can help fill in the blanks and to point me in the right direction so I don't spend a lot of hours only to find out I made a wrong turn at the beginning.
Maybe the piece you're missing is the idea of using a query with joins to pull in data from multiple tables. For instance (just incorporating a couple of your tables):
SELECT Dept_Name, Emp_Name, Stat_Name ...
FROM schedule
INNER JOIN departments on schedule.Dept_ID = departments.Dept_ID
INNER JOIN employees on schedule.Emp_ID = employees.Emp_ID
INNER JOIN status on schedule.Stat_ID = status.Stat_ID
...
where ....
Note also that a schedule table that contains all of the information needed to be displayed on the final page is not in the spirit of relational data modeling. You want each table to model some entity in your application, so it might be more appropriate to rename schedule to something like shifts if each row represents a shift. (I usually use singular names for tables, but there are multiple perspectives there.)
This is, frankly, a very difficult question to answer because you could get a million different answers, each with their own merits. I'd suggest you take a look at these (there are probably better links out there too, these just seemed like good points to note) :
http://www.devshed.com/c/a/MySQL/Designing-a-MySQL-Database-Tips-and-Techniques/
http://en.wikipedia.org/wiki/Boyce%E2%80%93Codd_normal_form
http://www.sitepoint.com/forums/showthread.php?66342-SQL-and-RDBMS-Database-Design-DO-s-and-DON-Ts
I'd also suggest you try explaining what it is you want to achieve in more detail rather than just post the table structure and let us try to figure out what you meant by what you've done.
Often by trying to explain something verbally you may come to the realisations you need without anyone else's input at all!
One thing I will mention is that you don't have to denormalise a table to report certain values together, you should be considering views for that kind of thing...