Object Relation Class Diagram - database

I am designing a Object Relational Database and here is my Class Diagram:
http://canning.co.nz/AdvancedDatabase/Class_Diagram.png
My Computer Class has a 1-1 relationship with the CurrentUser Class. When creating the Object in code, the Computer Class has a CurrentUser Object as an attribute (CurrentUser_objtyp).
Here is the code:
create type Computer_objtyp as Object (
CompNo Number,
CompName Varchar2(20),
CompOS Varchar2(20),
CompProcessor Varchar2(20),
CompRAM Varchar2(20),
CurrentUser_obj CurrentUser_objtyp,
HardDriveList_var HardDriveList_Vartyp,
member function getCompName return varchar2)
/
My question is this:
As the Computer Class has this attribute, does the Computer Class need the attribute listed with the other attributes (CompNo, CompName, CompOS, CompProcessor, CompRAM), or is the relationship link to the CurrentUser Class sufficient?

It all depends on the exact definitions of computer and currentUser. A few examples:
If you perceive a computer as the machine, then does it have no current user, because it needs no user at all. Users belong to the OS.
If you see the current user as the person who has hired computer time on this computer, then is it important.
If you see the current user as the current owner of the computer, then might it be otherwise and could the computer be a feature belonging to the user.
If the current user is an employee of a company and leasing the computer for his work, then is it important to have a link from the computer to the combination company/user, hence could you have a reference to a contract.
You have used a compositional relationship to describe the relationship between the computer and the user. That implies that a computer has a currentuser and that the life span of the current user depends on the life span of the computer. Then should the current user directly or indirectly be part of the list of variables of the computer.
On the ohter hand have you also a compositional relationship between a peripherical device and the computer. That is hard to understand. An association is the most likely relationship between a peripherical device and a computer.

Related

Database : Account table with Joined Tables Inheritance

I have Joined Tables Inheritance in my database : a Client table that can be a Company or a Person. I need to create an account for the client but only one if it's a person and one or many if it's a company. I also have users for backoffice that also need an account. So I tried this but I'm not sure if it's a good idea or not. So is it a good idea or not pls ?
Edited Thanks to The Impaler :
enter image description here
Your model is already pretty good, but you should fix/improve the following issues:
By setting the multiplicity 1 at the sides of Company and Person, the current model states that each client must be associated both with a company and a person! You have to fix this by changing the multiplicity to 0..1 and possibly add an invariant that requires each client to be either a company or a person (in a constraint box attached to the class rectangle).
Since, in general, not every company and not every person is a client, you should either change the multiplicities of their association ends at the Client side to 0..1 or rename these classes/tables to CompanyClient and PrivateClient.
In UML, the names of classes should not be underlined.
In UML, the standard ID attribute(s) of a class (called primary key in databases) have to be desginated by "{id}" appended at the end of the attribute declaration line, and not by underlining the attribute(s) concerned.
It's not good practice in UML, to redundantly represent reference properties both with associations and in the form of attributes, as you do with your #-prefixed attributes. Just drop these non-UML syntax attribute declaration lines.
Better rename your AccountCompany class to AccountsByCompany.

Is a Value Object that is used many times an entity?

The question might not be very clear in the title, let me explain:
In my model, I have an Person, that has an Address. However, many Persons can share the same Address.
As I was defining my model, I assumed that Person is an Entity, but Address a Value-Object since if you change a single property of the Address, well it's not the same Address anymore.
Since multiple Persons can share an Address, if I jump right into the database implementation, and naively assume that person has some address_xxxx fields, wouldn't it generate too many duplicates in the database ? Isn't it better that person has an address_id field, related to an address table ? If so, then Address is an Entity right ?
Is a Value Object that is used many times an entity?
No, but it depends...
It is often the case that a value object is actually a proxy identifier for an entity, that you may not have explicitly realized in your model.
For example:
1600 Pennsylvania Ave NW
Washington, DC
20500
If you look at that carefully, you'll see embedded in it
The name of a street
The name of a city
If those are references to a street/city entities in your model, then "address" is the representation of the current state of some entity (ex: "The White House").
Complicating things further - you want suitable abstractions for your model.
Consider money:
{USD:100}
That's a value type, we can replace any USD:100 with a "different" USD:100
{USD:100, SerialNumber:KB46279860I}
That's still a value (it's state), but it the state of a specific bill that exists in circulation (somewhere). What we have here is an information resource that is describing an entity out in the real world, somewhere.
You also need to be careful about coincident properties. For example; the name of the street changes -- should the value of address change? If the model cares about the current identifier of a location, then perhaps it should. If the model is tracking what information you put on an envelope two months ago, then it certainly shouldn't. (In other words, when we changed the label for the street entity, the label already printed on the envelope entity didn't change).
It's an important question, but the answer changes depending on what you are modeling at the time.
In my model, I have an Person, that has an Address. However, many
Persons can share the same Address.
Isn't it better that person has an address_id field, related to an
address table ? If so, then Address is an Entity right?
You have to recognize that there are two distinct models, a domain model and a persistence model and both may not agree on whether a concept is an entity or a value.
The first thing you have to do is ask yourself what is an address from the domain perspective? Is your domain interested in the lifecycle of addresses or they are just immutable values? For instance, what happens if there is a typo in an address? Do you simply discard the incorrect one and replace it or would you rather modify the original address details to track it's continuity? These questions will help you to determine whether an address is an entity or a value from the domain perspective.
Now, a concept may be a value in the domain while being an entity in the persistence model. For instance, let's say that you aren't interested in the lifecycle of addresses in the domain, but you are very concerned about optimizing the storage space. In that case, you could give identifiers to unique addresses in the DB and use that for relationships rather than copying the same address details multiple times.
However, doing so would introduce additional tensions between your models, so you must be sure that there are real benefits to do so.

ER model design

I have three tables: user, friend and family.
User is entity.
Friend is relationship.
Family is relationship.
However, if I would like to set privacy level which can control who can view my full information. i.e. Only friend can see my hobbies, and only family can see my current location.
I don't know how I can implement this on ER design.
Option 1:
User{
attribute 1: ID;
[other attributes]
}
Friend{
Attribute 1: FriendID;
}
Family{
Attribute 1: family ID;
}
How can I meet the requirements? Still confused about it. Anyone has a rational solution ?
ER diagrams are really a seperate issue from security. ER diagrams just state what exists and how it is realated.
The best place for this kind of secuiry is in the model. When you someone asks for your current location, check if they are your family, etc...
This is especially true since current location is likely to be calculated from GPS, not stored as an entity in the database. If it is, you could potentially include a forign key from current location to familyID that would tie these together.
If this doesn't make sense, please provide more details on hobbies and current location.

Django - Designing Model Relationships - Admin interface and Inline

I think my understanding of Django's FK and admin is a bit faulty, so I'd value any input on how to model the below case.
Firstly, we have generic Address objects. Then, we have User's, who each have a UserProfile. Through this, Users belong to departments, as well as having addresses.
Departments themselves can also have multiple addresses, as well as a head of department. So it might be something like (this is something I'm just hacking up now):
class Address(models.Model):
street_address = models.CharField(max_length=20)
etc...
class Department(models.Model):
name = models.CharField(max_lenght=20)
head_of_department = models.OneToOneField(User)
address = models.ForeignKey(Address)
class UserProfile(models.Model):
user = models.ForeignKey(User, unique=True)
address = models.ForeignKey(Address)
department = models.OneToOneField(Department)
Anyhow, firstly, is that the right way of setting up the relationships?
And secondly, I'd like it to appear in the admin that you can edit a department, and on that page, it'd have an inline list of all the addresses to also edit. I've tried setting up an AddressInline class, and attaching it as an inline to Department.
class AddressInline(admin.TabularInline):
model = Address
class DepartmentAdmin(admin.ModelAdmin):
inlines = [AddressInline]
However, when I try to display that, I get:
Exception at /admin/people/department/1/
<class 'people.models.Address'> has no ForeignKey to <class 'people.models.Department'>
Cheers,
Victor
Since it seems you want a UserProfile or Department to have potentially many addresses, your ForeignKeys are backward. A single ForeignKey can only point to one model instance, whereas there is no limit on the number of ForeignKeys that can point to a single model instance. So your ForeignKey should be on Address (in which case your inline would work as-is).
The complicating factor is that you have a single Address model and you want to relate it to two other models; a single ForeignKey on Address can't point to both UserProfile and Department. One solution is to have two address models (DepartmentAddress, with a ForeignKey to Department, and UserAddress, with a ForeignKey to UserProfile). You could reduce duplication in your code by having these both inherit from an abstract base class containing all the data fields, but you still end up with two mostly-identical tables in your database.
The other option is to have a GenericForeignKey on Address, which can point to an instance of any model. Your inline would then need to become a GenericInlineModelAdmin. This violates pure database normalization and doesn't allow your database to do proper integrity checking. If you had potentially more models in the future that would also have addresses, I'd consider this; if it's likely to be limited to only the current two, I might go with the above option instead.
I read your models what you want from your models as:
A department has one to many addresses
A department has one and only one user (as head of department)
A user (through his profile) belongs to one to many departments
A user (through his profile) has one to many addresses
If that was your intent, meaning that there is no case where a user will NOT have an address or a department, and no case where a department will not have an address or a head of department; then I would say your models are OK should read:
class Department(models.Model):
name = models.CharField(max_lenght=20)
head_of_department = models.OneToOneField(User)
address = models.ForeignKey(Address)
class UserProfile(models.Model):
user = models.ForeignKey(User, unique=True)
address = models.ForeignKey(Address)
department = models.OneToOneField(Department)
class Address(models.Model):
street_address = models.CharField(max_length=20)
...
class Meta:
abstract = True
class UserAddress(Address):
user_profile = models.ForeignKey(UserProfile)
class DepartmentAddress(Address):
department = models.ForeignKey(Department)
Read more about abstract classes.
What your models are not contemplating are the possibilities that two Users will have the same address, and/or that two departments will have the same address. Since you are not specifying a unique constraint on address (that I can see), I assume that you are OK with a real-world address showing up more than once in your Address table.
If that is OK with you; fine.
The error message you are getting is stating a fact: there is no foreign key in Address to Department. You will have to revert that relationship for the inline to work. Meaning, when editing an address you can edit any departments associated with it; but not the reverse. With the models I suggest above you should not see this error.
See the example from the docs. Notice how an Author has many Books and how the many side of the relationship is the one that can be inline.

DB design for multiple types of entities

I need to develop an application where there will be 4 types of user entities (administrators, partners, companies and clients), each user type has it's own set of details and they all should be able to do common operations like send messages, make payments and so on. These operations should be kept on a single table but they need to reference the exact user despite it's type.
What database design would be more appropriate?
I'd say this is a perfect case for inheritance. Put the common attributes in one table and inherit that to add custom attribute for your different user types.
Chaos answer seems a bit messy to me, alltough it'd be useful if you don't know in advance what the properties you need to store are.
"I would just like to add one more thing, you suggest I have a table per each user type... I prefer this approach however how would I design a schema where I can say that user id 7 (admin) sent a message to user id 537 (client)? Or that a payment was received by user id 70 (company)?"
There is nothing to stop you from doing that. Have a table {sender recipient message(-id)} with primary key all three attributes and two FK {sender} and {recipient}. The FK's refer to the primary key of the table that holds the COMMON attributes of all users.
Now, your next question may be, "but I want a rule to say that no user of type X can directly send a message to any user of type Y".
That is the point where any current IMPLEMENTATION of a (so-called) relational DBMS shows its weaknesses. Even Oracle or DB2 can't do that declaratively. There is simply too very much for me to say about that subject to fit in this response.
BTW You seemed to have taken an interest in my response despite all the downvotes. Really appreciate that.
Have a look at the three ways to do that in the Patterns of Enterprise Application Architecture:
http://martinfowler.com/eaaCatalog/singleTableInheritance.html
http://martinfowler.com/eaaCatalog/classTableInheritance.html
http://martinfowler.com/eaaCatalog/concreteTableInheritance.html
The choice depends on how many properties the 4 types of user entities will be sharing and also on the use cases that your system will require.
user
================
id
user_type_id
name
etc
user_type
================
id
name (admin, partner...)
etc
user_detail
================
id
user_id
user_detail_type_id
value
user_detail_type
================
id
name
user_type_to_user_detail_type
================
id
user_type_id
user_detail_type_id
(maps which user types have which detail types)

Resources