I have found similar questions in this forum, but any of them could bring my mind to a solution, so I thought that somebody could know the answer.
I have this database scenario:
merchandises, suppliers and orders. These are tables, and I have another two tables: orders_merchandises and suppliers_merchandises.
these tables are like this:
merchandises
-id
-name
suppliers
-id
-name
orders
-id
-supplier_id
orders_merchandises
-order_id
-merchandise_id
suppliers_merchandises
-supplier_id
-merchandise_id
The rule is:
The suppliers can supply only merchandises that they are able to. So, I have the table suppliers_merchandises to register each suppliers for the merchandises that they supply to the store.
So the orders must restrict suppliers to supply only merchandises "pre-recorded" in the suppliers_merchandises.
I hope that I could explain clear enough.
So, I need a foreign key for multiple tables, like this:
ALTER TABLE suppliers_merchandises
ADD FOREIGN KEY FK_NAME (supplier_id, merchandise_id)
REFERENCES (orders.supplier_id, orders_merchandises.merchandise_id)
But, unhapply that not works.
Anybody knows if are there any way to do what I want to do?
It can be in any dbms. SQLServer, Firebird, or any other
Use composite keys and relationships:
Add a supplier_id column to orders_merchandises
Make a FK from orders_merchandises to order on (order_id, supplier_id)
Create a FK from orders_merchandises to supplier_merchandiseson (supplier_id, merchandise_id)
This will lock orders from suppliers to only be for merchandise found for them in supplier_merchandise.
You may want to change primary keys from surrogates to composites, and discard existing competing FKs.
Related
I'm currently designing my data base using postgresql with Django and I was wondering: What is best practice - having several instances of the same model with the same value or a many to many relation ship?
Let me elaborate. Let's say I'm designing a store. The store sells items. Items can have one or many statuses (e.g. ordered, shipped, delivered, paid, pre-ordered etc.).
What would be a better practice:
Relating the items to their status via a many-to-many relationship, which will lead to one status having hundreds of thousand and later millions of relations? Will so many relations become problematic?
Or is it better for each item to have a foreignkey to their statuses? So that each status only has one item. And if I would like to query all the items that have the same status (e.g. shipped), I would have to iterate over all statuses with a common name.
What would be better, especially for the long term?
I would recommend going with a many-to-many relationship.
Hundreds of thousands or even millions of relations should not be a problem. The many-to-many relationship is stored as a table with id, item_id, status_id. SQL will be performant at querying the table either by status_id or item_id even if the table gets big. This is exactly the kind of thing it was built to handle.
Let me elaborate. Let's say I'm designing a store. The store sells
items. Items can have one or many statuses (e.g. ordered, shipped,
delivered, paid, pre-ordered etc.).
If many people will have this many itens you should use manytomany relations, better let django handle with this "third table", since this table just hold ids you can interate over them using reverse lookup, i do prefer using many to many instad of simple foreignkeys.
In your case, who you will handle when your User will hold many itens? like what if my User buy one potato and 2 bananas? you will duplicate the tuple in your User Table to tell "here he have the potato and in this second one he have the banana"? so you will be slave of Disctinct attribute while you still dirtying your main table User
...
class Item(models.Model):
...
class User(models.Model):
items = models.ManyToMany(Item)
So when i query my Item and my User will only bring attributes related to them... while if you use item inside of User Model you will have multiple instances of same user.
So instead of use User.items.all() you will use User.objects.filter(id=id)and them items = [user.item for user in User.objects.filter(id=id)]
Look how complex this get and makeing your database so dirty
User has an email address and a display name.
Both of these must be unique.
Both of these must be updatable as long as either is not being used already.
A User table will exist with additional non-key attributes and a guid ID.
How to model to support efficient query check if email address or display name is already being used?
Should I create a table with the guid as Key, no range, and 2 separate GSI one for email and one for display name (each being the key)? Both will also have a second field with the guid id of the user. Or should these be completely separate tables, or ????
Thoughts, is there a better way?
Thanks.
There are 3 ways you can design that I can think of:
As you have mentioned, a table with guid and 2 separate GSI one for email and other for Name.
You have stated that both the fields had to be unique, so potentially you can make any one of them as hash and create GSI for other.(This will run into problem as you mention that you need to update Email & Name as well, for that you have to delete old record and add a new record with same attributes and updated Hash keys)
Advantage of this would be that you need to pay less as there will be only one GSI compared to #1.
Another option is to use CloudSearch, your DynamoDB table can be integrated with cloudSearch, in this option you can simply create a table with guid no need to add any GSI, whenever you want to search you can search on CloudSearch to get the output.
One more advantage you will get in CloudSearch is that you will be able to query on any attributes of the table and can use different filters on them.
One thing you need to see it that price difference between #2 and #3, you can go with anyone which is better suited in terms of price and functionality.
If you implement this with other ways feel free to share it.
Hope that helps
I have problem which is easy to solve with pure SQL but I need to solve it with Doctrine in YAML.
I have well known db tables users and friends. Where users table has primary key user_id and friends has friend_id and friend_with_id which uses user_id from table user. My problem starts when I need to add there one more column mood. With SQL I add to table friends onemore column named mood and it's done with doctrine I can't find any solution.
For better understanding I add db scheme:
I dont see any self-reference relationship here. Both friend_id and friend_with_id points to users.user_id. What I see is, two one-to-many relationships from the user side OR two many-to-one relationships from the friends side.
So, there will be two ArrayCollection objects (ManyToOne) in the Friend entity corresponding to friend_id and friends_with_id. Similarly two ArrayCollections (OneToMany) on the User entity, namely, myFriends and friendsWith.
I'm having some problems with the following...
I have a table with phone numbers. I want to use the same table for both users and companies. A user can have several phone numbers and a company too. So i want a One to many unidirectional relationship with two different join tables. One linking phone numbers to users, the other linking phone numbers to companies.
This is solution following the doctrine2 manual chapter 5.9 found here: (click)
My users entity holds this code:
/** #ORM\ManyToMany(targetEntity="Application\Entity\PhoneNumber")
* #ORM\JoinTable(name="user_phone_number_linker",
* joinColumns={#ORM\JoinColumn(name="user_id", referencedColumnName="id")},
* inverseJoinColumns={#ORM\JoinColumn(name="phone_number_id", referencedColumnName="id")}
* )
*/
protected $phone_numbers;
I use a unidirectional one to many because the thing is I can't make a bidirectional one because if I refer back to the user I cannot use the same phone number entity class for the company. Now it all works fine, but when I delete a phone number I get the following error:
An exception occurred while executing 'DELETE FROM phone_number WHERE id = ?' with params {"1":1}:
SQLSTATE[23000]: Integrity constraint violation: 1451 Cannot delete or update a parent row: a foreign key constraint fails (database/user_phone_number_linker, CONSTRAINT user_phone_number_linker_ibfk_11 FOREIGN KEY (phone_number_id) REFERENCES phone_number (id))
If I set the ON DELETE CASCADE value manually in the database it works fine, but this is not the idea of using doctrine2 and I think I should be able to solve it within the code without going to my phpMyAdmin panel. Somehow the cascading from the phone number towards the join table should be initiated on deletion, but without making a reference back to the join table from the phone_number entity.
Hope someone smart can help me solve this.
EDIT
In the meantime I learned a lot more about Doctrine2 and reviewing my old question made me realize that this is not a correct way to store several phoneNumbers in one table in the first place. To be able to store user phone numbers and company phone numbers in the same table I should use table inheritance with a discriminator column. The column should hold some user/company discriminator.
Because of this column the doctrine ORM will "know" if that phoneNumber is actually a user or a company phone-number. I need to make two different entity definitions following the single table inheritance mapping principles from the doctrine 2 specs.
One class UserPhoneNumber will have a many-to-one relationship with User the other called CompanyPhoneNumber a one-to-many relationship with Company. I don't necessarily need a join column, the user_id or company_id columns can be in the phone-number table. In the User class the Company association is omitted and in the Company class the User association is omitted (database should allow null values for those columns).
If I do use a join table it is according to the one-to-many unidirectional with join table description in the Doctrine2 specs
READ MORE
Otherwise you can also read more on associations and cascade issues here on this elaborate Doctrine2 in depth website.
As you said, your relation is unidirectional. You've defined a relation from Users to PhoneNumbers. The cascade delete will work when you delete a User, it will remove all rows in user_phone_number_linker because that's the relation you've defined.
If you want to do it the other way, you've got to create a relation from PhoneNumbers to Users. Doctrine needs it to work for you. But you have the problem that the entity is shared by two other entities, Users and Companies.
Keep in mind that entities are objects, not tables. So you could try to create two entities to the same table, one named PhoneNumberUsers and the other PhoneNumberCompanies. This way you'll be able to create the needed relation to do the cascade delete. I haven't tested by myself, but I think it could work.
By the way, you can remove the oncascade parameter on the Users' entity join table. I've the same scenario as you with users and roles, and I haven't used it. I think it's only needed when you want to cascade from entity to entity. I'm not sure about that, but that's what I've been experiencing until now.
My bad,
The phone number user relationship is regarded a Many-To-Many relationship, so if want to remover the phone number I should not only remove the phone number itself, but I have to explicitly remove the phone number from the user as well. So in the Controller like this:
// Remove the phone number user connection from the database
$user->removePhoneNumber($phone_number);
// Remove the phone number from the database
$em->remove($phone_number);
I just thought the unique restriction which makes the relationship to a unidirectional One-To-Many would be enough to make doctrine take care of it. That was not correct.
I am trying to implement some tables that mimic inheritance in a relational (sqlite) database. My goal is to have one master table with general fields, and some child tables with specialized fields. Every record in the master table will have exactly one counterpart in exactly one of the specific tables. What I want looks like this:
Master table:
id (PK) #Your average web2py unique auto-incrementing int field
#Some general fields
Child tables:
id (PK, FK referencing the PK of the master table)
#Some specialized fields
Having a default "id" PK for each child table has no use to me. All I need is an FK reference to the master table, which can serve as the PK for the child tables. This means that the PK of the child tables will be unique, but will contain gaps. This is because a child table will only reference some of the records of the master table.
I get the impression that doing this (not giving the child tables the regular "id" PK) is against the Web2py way. So my questions are as follows:
Is this a Bad Idea™? If so, why?
How would I implement this? Can Web2py handle tables that don't have an auto-incrementing int as PK?
It's very important for me to apply the correct style and practice when writing code. I am open to alternative approaches.
Thank you for your help.
See the book section on keyed tables. If this is a database specifically for use with web2py, I suggest you stick with the standard web2py approach:
db.define_table('master', ...)
db.define_table('child', Field('master', db.master))