Po dev-data-model-object relationalmapping.100926a
-
Upload
projectopen -
Category
Documents
-
view
480 -
download
1
description
Transcript of Po dev-data-model-object relationalmapping.100926a
Object Relational Mapping in ]po[The ]project-open[ Data-Model , Frank Bergmann, 2010-09-22
This tutorial explains how the ]po[ data-model represents the is-a inheritance relationship of object types.
]project-open[ 2010, Data-Model / Frank Bergmann / 2
The Problem: Mapping Objects into Tables
How should ]po[ represent inheritance in the database?
There are two main approaches known from database theory:– “Classical Relational Model”:
Every object type is mapped to its own table that includes all attributes of all super-types.
– “Object Oriented Data-Model”:Every object type is mapped to its own table. The attributes of the super-types are stored in the tables of the super-types.
Let’s consider the following class diagram at the right as an example.
Project
project_name
customer_id…
TimesheetTasks
material_id. . .
planned_unitsbillable_units ticket_sla_id
Ticket
ticket_status_idticket_type_id
. . .
last_modified
object_type
Object
(Part of the ]po[ object model.Timesheet Task and Ticket are sub-types of
Project.)
]project-open[ 2010, Data-Model / Frank Bergmann / 3
Classical Relational Model
In this model, every “concrete” object type (that excludes “Object”) is mapped into its own table.
Every table contains all fields from all super-types.
This model seems to be a kind of industry standard.
Pros:– Fast access to all fields– Standard”
Cons:– Duplication of fields, making
it difficult to write reusable code
last_modified
object_type
objects projects
project_namecustomer_id…
last_modified
ticket_sla_id
tickets
ticket_status_idticket_type_id
. . .
project_namecustomer_id
last_modified
timesheet_tasks
material_id. . .
planned_unitsbillable_units
project_namecustomer_id
last_modified
]project-open[ 2010, Data-Model / Frank Bergmann / 4
]po[ Object Relational Model
In this model, every object type (including abstract types like “Object”) is mapped into its own table.
Every table contains all fields from all super-types.
Every table includes a “pointer” (project_id, task_id, ticket_id) to the objects.object_id. This way it is possible to access the attributes stored in the tables of the super-types.
Pros:– No duplication of fields– Code reuse possible
Cons:– One or more “joins” are required to
get all fields of an object
project_id
projects
project_name
customer_id…
task_id
timesheet_tasks
material_id. . .
planned_unitsbillable_units
ticket_id
ticket_sla_id
tickets
ticket_status_idticket_type_id
. . .
object_type
objects
object_id
]project-open[ 2010, Data-Model / Frank Bergmann / 5
Additional Advantages of the ]po[ Object Model
During the course of the development of ]po[,we have found a large number of important advantages of the object oriented data-model. DynField SQL Meta-Data Model:
The DynField systems allows to extend objects with new attributes at run-time.
Permissions:We can define permissions generically on the “object” level.
Other “Application Services”:Many services can work generically for many types of objects. For example the “full-text indexing” service can index and retrieve any type of object, as long as the object implements the “FTI search interface”. ]po[ includes some 10 such services.
Easy Extensibility:It is very easy to create new sub-types. “Portlet Components” built for the base-type will usually still work for the sub-types.
project_id
im_projects
project_name
customer_id…
task_id
im_timesheet_tasks
material_id. . .
planned_unitsbillable_units
ticket_id
ticket_sla_id
im_tickets
ticket_status_idticket_type_id
. . .
object_type
acs_objects
object_id
(The actual names of the tables. The “acs_” prefix indicates “core” tables, while “im_” stands for
“Intranet” tables (the prefix “in_” was taken already))
]project-open[ 2010, Data-Model / Frank Bergmann / 6
The acs_objects Table
All objects “inherit” from acs_objects, so acs_objects contains an entry for every object in the system.
acs_objects contains the field “object_type”, so we can now the type of every object.
Services on the acs_object level:– Permissions– DynFields– Is-part-of hierarchy– last_modified
Column | Type | Modifiers
-------------------+--------------------------+----------------------
object_id | integer | not null
object_type | character varying(100) | not null
context_id | integer |
creation_user | integer |
creation_date | timestamp with time zone | not null default now()
creation_ip | character varying(50) |
last_modified | timestamp with time zone | not null default now()
modifying_user | integer |
modifying_ip | character varying(50) |
tree_sortkey | bit varying | not null
max_child_sortkey | bit varying |
last_audit_id | integer |
object_id: A number from sequence acs_object_id_seq
object_type: An object type from table acs_object_types
context_id: Parent of the is-part-of hierarchy. The parent is usually the package.
creation_user: Who created the object? creation_ip: From where did creation_user
login? last_modified: Last modification date
(maintained by the GUI) modifying_user: Who modified? modifying_ip: From where did
modifying_user login? tree_sortkey: Hierarchical index for
context_id max_child_sortkey: ??? last_audit_id: Last audit record written for
this object.
]project-open[ 2010, Data-Model / Frank Bergmann / 7
]po[ Data-Model
object_id
im_biz_objects
object_id
object_type
acs_objects
group_idgroup_name
groups
profile_idprofile_gif
im_profiles
users_contact
<Home Address><Work Address>
im_employees
<Payroll Info><Recruiting Info>
party_idemailurl
persons
person_idfirst_nameslast_name
users
user_idusernamepassword…
company_id
im_companies
main_office_id
company_namestatus_idtype_id
…
office_id
<Address>
im_offices
office_status_idoffice_type_id
company_id
cost_center_id
cost_center_name
im_cost_centers
cost_center_code
department_p
im_costs
cost_id
cost_name
cost_nr
project_id
customer_id
provider_id
cost_status_id
cost_type_id
effective_date_id
payment_days
amount
currencytax
vat
…
cost_center_id
invoice_id
contact_id
im_invoices
invoice_nr
office_id
item_id
item_name
im_invoice_items
project_id
invoice_id
item_units
item_uom_id
price_per_unit
currency
sort_order
item_type_id
item_status_id
description
payment_id
cost_id
im_payments
company_id
provider_idamount
expense_idext_company
im_expenses
ext_vat_numberbillable_p
…bundle_id
material_id
…
im_materials
material_namematerial_uom_id
task_id_one
im_ts_task_deps.
task_id_twodepend._typedifferencehardness
task_id
invoice_id
im_timesheet_tasks
material_iduom_id
planned_unitsbillable_unitscost_center_id
priorityprice_id
uom_id
im_timesheet_prices
company_idtask_type_id
material_idprice
project_id
im_projects
project_lead_id
project_name
project_status_idproject_type_id
supervisor_id
project_nrproject_pathcustomer_id
start_dateend_date…
…
…
MainBusiness
Objects
Gantt,Timesheet
& Helpdeskuser_id
im_hours
project_id
dayhours…
Users &Groups
Financials
rel_idobject_id_one
acs_rels
object_id_two
rel_idsort_order
im_ticket_ticket_rel
ticket_id
ticket_sla_id
im_tickets
ticket_status_idticket_type_idticket_prio_idticket_contact_idticket_assignee_id
ticket_queue_id. . .
bundle_id
im_expense_bundle
<Type Info>object_type
acs_object_types
SQL Meta-DataSystem
PermissionSystem
acs_permssions
object_idgrantee_idprivilege
acs_privilege
privilegepretty_name
context_id<Audit info>
…
attribute_id
acs_attributes
object_typepretty_name
…
attribute_id
im_dynfieldattributes
widget_name
parties
]project-open[ 2010, Data-Model / Frank Bergmann / 8
Exercises
Exercise 1: Show all fields of a ticket:Go to the ]po[ GUI -> Helpdesk and click on the first ticket. Note the ticket_id variable in the URL. Write a SQL to pull out all fields for this ticket from the tables acs_objects, im_projects and im_tickets.
Exercise 2: Show all fields of a user:Go to the ]po[ GUI -> My Account. Note the user_id in the URL. Write a SQL to pull out all fields for this user from the tables objects, parties, persons and users.
]project-open[ 2010, Data-Model / Frank Bergmann / 9
Exercise 1: Getting all fields of a Ticket
The following SQL pulls out all fields for a single ticket.
Please note that we need to access three different object types (acs_objects, im_projects and im_tickets) to gather all fields.
SELECT*
FROM acs_objects o,
im_projects p, im_tickets t
WHERE o.object_id = p.project_id and
o.object_id = t.ticket_id ando.object_id = 12345;
project_id
im_projects
project_name
customer_id…
task_id
im_timesheet_tasks
material_id. . .
planned_unitsbillable_units
ticket_id
ticket_sla_id
im_tickets
ticket_status_idticket_type_id
. . .
object_type
acs_objects
object_id
]project-open[ 2010, Data-Model / Frank Bergmann / 10
Exercise 2: Getting all Fields of a User
The information about users is spread across three different tables:
Parties is a common super-type for both users and groups, allowing to build recursive group structures.
Persons represent “natural persons”. Users represent persons with the
right to login to a ]project-open[ server.
Im_employees include additional fields for users who are employees. However, “Employee” has not been defined as an object type.
users_contact includes address information that can be attached to any type of user.
object_id
object_type
acs_objects
users_contact
<Home Address><Work Address>
im_employees
<Payroll Info><Recruiting Info>
parties
party_idemailurl
persons
person_idfirst_nameslast_name
users
user_idusernamepassword…
SELECTo.*,pa.*,pe.*,u.*,e.*,uc.*
FROM acs_objects o, parties pa, persons pe,
users u, im_employees e, users_contact ucWHERE o.object_id = pa.party_id and
o.object_id = pe.person_id ando.object_id = u.user_id ando.object_id = e.employee_id ando.object_id = uc.user_id;
group_idgroup_name
groups