In SQL you can describe a binary relation with a table like
Husband | Wife
We know that an husband can have only one wife, and viceversa, so that's a 1:1 relationship, and you can specify costraints such that if you add an husband that is already in the table you get an error, right?
If you add a third column like this
Husband | Wife | Country
We know that in some country one husband can have many wives; now you cannot put easy costraints, you have to deal with the third column.
So from a binary relation we get a ternary relation with different behavior that depends on the third column.
This example is stupid and useless, do you know any other example?
(other example of ternary relationship such that one of the column changes the tuple behavior?)
Thank you.
EDIT:
Another point of view to see my problem:
You have any binary relationship, within a domain: do you know any binary relation that changes costraints (or behavior) as domain changes?
Another example might be that you can apply coupons towards an order, but for certain coupon types you can only apply one per order whereas other coupon types may be combined.
Related
I'm new to ER diagrams. I noticed that draw.io (which was recommended on Stackoverflow) does not have a one (optional) to one (mandatory) relationship.
Let's say, I have two tables "user" (id, affiliate_id) and "affiliate" (id). There doesn't have to be an affiliate, in which case user.affiliate_id would be null.
However, if there is an affiliate, then user.affiliate_id will link to affiliate.id.
So wouldn't that be a one (optional) to one (mandatory) relationship?
PS: I was thinking that maybe user.affiliate_id must not be null in a strict sense. However, it doesn't break the foreign key constraints (at least for SQLite 3).
I think you are describing a one-to-many relationship. One user can (optionally) be associated to one affiliate, but the same affiliate can be associated to more than one user.
Or am I misunderstanding?
Yes, you are right, that would be a zero/one (or zero/many) to one relationship type, which has to be shown in the diagram. There are different notations for ER diagrams (and it's therefore, in fact, preferable to use UML class diagrams). For instance, in the notation used by Oracle the optional end of the connection line representing the relationship type is annotated with both a zero and a one symbol. In UML, the annotation of the optional association end would be 0..1 (if single-valued) or 0..* (if many-valued).
A "group" belongs to a "owner" and has many "members". Both the "owner" and the "members" can create "events" under the "group."
Then I need to restrict members to create events under particular groups.
So I tried to add a boolean column to groups table:
When true - this "group" allow all "members" to create "events."
When false - this "group" doesn't allow "members" to create "events", which means only "owner" can create events.
but what should this column name be like?
allows_members_to_create_events
allows_only_owner_to_create_events
requires_owner_authority_to_create_events
other ones?
Or am I doing something wrong with my database design?
I know I'm a little bit too picky about naming but I always have trouble with this kind of naming problem and waste times. So I asked here.
A good name is one of the hardest things to do in coding and I too spend silly time mulling over good naming.
One of my judging criterion is see how the name is being used.
In database point of view i.e. reading from the model source code, only_owner_can_create is a good explanatory name.
In controller point of view, you may want to write if group.allows_members_to_create? or unless group.only_owner_can_create
Having the context where this field will be used will help you greatly to determine the name.
Also you CAN have the best of both worlds - just use alias_methods to add more methods!
Instead of boolean column add numeric column to hold some numeric values. This numeric values are inserted based on the their levels. You have to define these levels in you application.
member_can_create_events would be my pick (single data point that I am).
That would give:
my_group.members_can_create_events?
Though I also agree with Mohanraj that a more complete solution might have users with levels and a column that relates to "users over level X can create events here"... but if you want a quick solution, the boolean column works just fine.
I am building an app that have the following requirements:
-> A User can be a player of different teams.
-> A Team can be of a sport type.
My question is:
-> Since for each sport type I want to store different information of a Player, what would be the best way to model that?
I have thought on having several models (and tables) for each kind of Sport, for example:
Basketball_Players, Football_Players and so on, but I am not sure if that would be a good approach. How do you usually do this on RoR?
I'd say you have two options, and I don't know that it's really possible to say which is the "most correct" way to do it without knowing the details of the requirements of your application.
What's a given is that you'll have a sport table and a player table. I can say that for sure. The question is how you connect the two.
Option 1: a single join table
You could have a table called player_sport (or whatever) with a player_id column, a sport_id column, and a serialized_player_data column or something like that, where you'd keep serialized player data (JSON, perhaps) depending on the sport. Pros: simple schema. Cons: not properly normalized, and therefore subject to inconsistencies.
Option 2: a separate join table for each sport
This is what you alluded to in your question, where you have a basketball_player, football_player, etc. Here you'd also have a player_id column but probably not a sport_id column because that would be redundant now that you're specifying the sport right in the table name. The need to have a serialized_player_data column would go away, since you'd now be free to store the needed attributes directly in columns, e.g. wrestling_player.weight_class_id or whatever. Pros: proper normalization. Cons: more complex schema, and therefore more work in your application code.
There's actually a third option as well:
Option 3: a combination of 1 and 2
Here you might do everything you would do in Option 2, except you'd move the common player attributes to the player_sport table and save basketball_player, etc. for the sport-specific attributes. So weight_class_id would stay in wrestling_player but player_sport would have height, weight, and other columns that are relevant to all sports.
If you're looking for a recommendation, I would probably do Option 2, or, if it looks like there's enough overlap for it to make sense, Option 3.
I'm using MS SQL Server 2008R2, but I believe this is database agnostic.
I'm redesigning some of my sql structure, and I'm looking for the best way to set up 1 to many relationships.
I have 3 tables, Companies, Suppliers and Utilities, any of these can have a 1 to many relationship with another table called VanInfo.
A van info record can either belong to a company, supplier or utility.
I originally had a company_id in the VanInfo table that pointed to the company table, but then when I added suppliers, they needed vaninfo records as well, so I added another column in VanInfo for supplier_id, and set a constraint that either supplier_id or company_id was set and the other was null.
Now I've added Utilities, and now they need access to the VanInfo table, and I'm realizing that this is not the optimum structure.
What would be the proper way of setting up these relationships? Or should I just continue adding foreign keys to the VanInfo table? or set up some sort of cross reference table.
The application isn't technically live yet, but I want to make sure that this is set up using the best possible practices.
UPDATE:
Thank you for all the quick responses.
I've read all the suggestions, checked out all the links. My main criteria is something that would be easy to modify and maintain as clients requirements always tend to change without a lot of notice. After studying, research and planning, I'm thinking it is best to go with a cross reference table of sorts named Organizations, and 1 to 1 relationships between Companies/Utilities/Suppliers and the Organizations table, allowing a clean relationship to the Vaninfo table. This is going to be easy to maintain and still properly model my business objects.
With your example I would always go for 'some sort of cross reference table' - adding columns to the VanInfo table smells.
Ultimately you'll have more joins in your SP's but I think the overhead is worth it.
When you design a database you should not think about where the primary/foreign key goes because those are concepts that doesn’t belong to the design stage. I know it sound weird but you should not think about tables as well ! (you could implement your E/R model using XML/Files/Whatever
Sticking to E/R relationship design you should just indentify your entity (in your case Company/supplier/utilities/vanInfo) and then think about what kind of relationship there is between them(if there are any). For example you said the company can have one or more VanInfo but the Van Info can belong only to one Company. We are talking about a one – to- many relationship as you have already guessed. At this point when you “convert” you design model (a one-to many relationship) to a Database table you will know where to put the keys/ foreign keys. In the case of a one-to-Many relationship the foreign key should go to the “Many” side. In this case the van info will have a foreign keys to company (so the vaninfo table will contain the company id) . You have to follow this way for all the others tables
Have a look at the link below:
https://homepages.westminster.org.uk/it_new/BTEC%20Development/Advanced/Advanced%20Data%20Handling/ERdiagrams/build.htm
Consider making Com, Sup and Util PKs a GUID, this should be enough to solve the problem. However this sutiation may be a good indicator of poor database design, but to propose a different solution one should know more broad database context, i.e. that you are trying to achive. To me this seems like a VanInfo should be just a separate entity for each of the tables (yes, exact duplicate like Com_VanInfo, Sup_VanInfo etc), unless VanInfo isn't shared between this entities (then relationships should be inverted, i.e. Com, Sup and Util should contain FK for VanInfo).
Your database basically need normalization and I think you're database should be on its fifth normal form where you have two tables linked by one table. Please see this article, this will help you:
http://en.wikipedia.org/wiki/Fifth_normal_form
You may also want to see this, database normalization:
http://en.wikipedia.org/wiki/Database_normalization
I've looked through similar questions but I'm still a little perplexed about something that seems to be a simple case in Rails.
Let's say I have a model class called Employee. One attribute of an employee is their security_clearance, which is a string that can be None, Some, or Full. No other values are valid. In other applications I'd probably represent this an Employees table that has a foreign key to the SecurityClearances table, which has exactly three rows. The SecurityClearances table has columns entitled code (e.g. SEC_CLEARANCE_NONE, SEC_CLEARANCE_SOME, ...) and value ("None", "Some", "Full").
How do I want to do this in Rails? Do I want has_one :security_clearance on Employee and belongs_to :employee on SecurityClearance? That doesn't seem to be quite right.
It seems nonoptimal to type out the string literals of None, Some, and Full everywhere, especially since the values to be displayed could change (for example, perhaps the string for the Some code will be change to be low clearance instead).
Update:
Now that I think about this some more, don't I really just want a belongs_to :security_clearance on Employee? That would do the trick, right? Employees need to know what their security clearance levels are, but security clearance levels have no tie to a particular employee.
Take a look at this plugin: http://github.com/mlightner/enumerations_mixin/tree/master
It allows you to define this like has_enumerated :security_clearance, besides also caching the SecurityClearance model, etc.
Without the plugin, though, you're right about the relationships.
Also check out the Enum Fields plugin from the GiraffeSoft folks:
http://giraffesoft.ca/blog/2009/02/17/floss-week-day-2-the-enum-field-rails-plugin.html