text:
Mapping Objects To Relational Databases
- Conrad Randolph Doyle
- 3 years ago
- Views:
1 Mapping Objects To Relational Databases An AmbySoft Inc. White Paper Scott W. Ambler Senior Object Consultant AmbySoft Inc. Portions of this White Paper have been modified from Scott W. Ambler s Building Object Applications That Work SIGS Books/Cambridge University Press, 1998 and Process Patterns SIGS Books/Cambridge University Press, This Version: February 26, 1999 Copyright 1998 Scott W. Ambler
2 ii Change History March/April 1998: The following additions have been made to this document: A discussion of determining the value of object identifiers (OIDs) in a distributed environment A discussion of determining the value of OIDs in a multi-vendor database environment A discussion of replicating objects across persistence mechanisms An example showing the various ways to map inheritance. A discussion of the process patterns applicable to mapping objects to relational databases A discussion of the issues involved with performing an initial data load Special thanks to Chris Roffler and Ben Bovee for pointing out needed improvements. May 16 th, 1998: I removed portions of the original document and moved them into my new persistence layer design white paper, downloadable from June 1 st, 1998: Minor updates to diagrams and pagination improvements November, 1998: Fixes to inheritance section. Career advice for data modelers added. Process patterns for OO modeling added. Minor spelling and grammar updates. February, 1999 Updates to mistakes in diagrams Improved discussion of why using data models as the basis for your OO model isn't advisable
3 iii Table Of Contents 1. THE OBJECT-RELATIONAL MISMATCH THE IMPORTANCE OF OBJECT IDS OIDS SHOULD HAVE NO BUSINESS MEANING OID UNIQUENESS STRATEGIES FOR ASSIGNING OIDS Using MAX() on an Integer Column Maintaining a Key-Values Table GUIDs/UUIDs Proprietary Persistence Mechanism Features The HIGH/LOW Approach To OIDs Implementing a HIGH/LOW OID HIGH/LOW OIDs In a Distributed Environment HIGH/LOW OIDs In A Multi-Vendor Environment REPLICATION OF OBJECTS THE BASICS OF MAPPING MAPPING ATTRIBUTES TO COLUMNS MAPPING CLASSES TO TABLES Implementing Inheritance in a Relational Database Mapping Several Classes To One Table MAPPING RELATIONSHIPS The Difference Between Association and Aggregation Implementing Relationships in Relational Databases Implementing Many-To-Many Relationships The Same Classes/Tables, Different Relationships CONCURRENCY, OBJECTS, AND ROW LOCKING PESSIMISTIC VS. OPTIMISTIC LOCKING STORED PROCEDURES TRIGGERS PROCESS PATTERNS FOR MAPPING OBJECTS TO RDBS WHY IS THE PERSISTENCE MODELING PROCESS PATTERN IMPORTANT? THE IMPLICATIONS? THE REALITIES OF MAPPING OBJECTS TO RELATIONAL DATABASES OBJECTS AND RELATIONAL DATABASES ARE THE NORM ODBC AND JDBC CLASSES AREN T ENOUGH THEREFORE YOU NEED A PERSISTENCE LAYER HARD-CODED SQL IS AN INCREDIBLY BAD IDEA YOU HAVE TO MAP TO LEGACY DATA BUT THE DATA MODEL DOESN T DRIVE YOUR CLASS DIAGRAM JOINS ARE SLOW KEYS WITH BUSINESS MEANING ARE A BAD IDEA AND SO ARE COMPOSITE KEYS YOU NEED SEVERAL INHERITANCE STRATEGIES STORED PROCEDURES ARE A BAD IDEA... 24
4 iv 9. SO WHAT S WITH THE ATTITUDE PROBLEM? SUMMARY REFERENCES AND RECOMMENDED READING GLOSSARY OF TERMS ABOUT THE AUTHOR INDEX... 33
5 This paper presents a practical look at the issues involved with mapping objects 1 to relational databases and should alleviate several common misconceptions prevalent in development circles today. Before you read any further, this paper is assumes that you want to develop object-oriented applications that are easy to extend and to maintain, that you are willing to invest the time during development to determine a persistence strategy that will achieve these aims. If your goal is to simply bang out a small application as quickly as you can, ignoring quality, then stop reading right now and just start hacking out some code. If your goal is to build something that will add long-term value to your organization, to build a quality object-oriented application, then read on. You have to make a conscious decision to do things right, and the first step is to take the time to understand what the right and wrong things are. This paper discusses many of the principles involved for successfully mapping objects to relational databases. You must consciously choose to build a quality application, and that takes time and an understanding of the basics. This paper presents the basics of mapping objects to relational databases. The material in this paper should be taken as a collection of strategies that you should follow whenever possible, and if you go against them then you should have a valid reason for doing so and know the implications of doing so. The strategies are based on my development experiences from small projects of several people to large projects of several hundred people, on projects in the financial, distribution, military, telecommunications, and outsourcing industries. I ve applied these principles for applications written in C++, Smalltalk, Visual Basic, and Java. The bottom line is that the material in this white paper is based on real-world experiences on a wide variety of projects. I hope that you find this paper of use. 1. The Object-Relational Mismatch The object paradigm is based on building applications out of objects that have both data and behavior, whereas the relational paradigm is based on storing data. The impedance mismatch comes into play when you look at the preferred approach to access: With the object paradigm you traverse objects via their relationships whereas with the relational paradigm you duplicate data to join the rows in tables. This fundamental difference results in a non-ideal combination of the two paradigms, although when have you ever used two different things together without a few hitches? One of the secrets of success for mapping objects to relational databases is to understand both paradigms, and their differences, and then make intelligent tradeoffs based on that knowledge. 2. The Importance of Object IDs We need to assign unique identifiers to our objects so that we can identify them. In relational terminology a unique identifier is called a key, in object terminology it is called an object identifier (OID). OIDs are typically implemented as full-fledged objects in your OO applications and as large integers, or several large integers for larger applications, in your relational schema. Figure 1 presents a diagram showing a possible implementation of an OID class and Figure 2 shows how an OID might be mapped to a column(s) in a table. Object identifiers (OIDs) are used to uniquely identify objects in a relational database. OIDs allow us to simplify our key strategy within a relational database. Although OIDs don t completely solve our navigation issue between objects they do make it easier. You still need to perform table joins, assuming you don t intend to traverse, to read in an aggregate of objects, such as an invoice and all of its line items, but at least it s doable. 1 This white paper does not discuss the design of a persistence mechanism in detail, the topic of a future AmbySoft Inc. white paper.
6 2 Another advantage is that the use of OIDs also puts you into a position in which it is fairly easy to automate the maintenance of relationships between objects. When all of your tables are keyed on the same type of column(s), in this case OIDs, it becomes very easy to write generic code to take advantage of this fact. 2.1 OIDs Should Have No Business Meaning A very critical issue that needs to be pointed out is that OIDs should have absolutely no business meaning whatsoever. Nada. Zip. Zilch. Zero. Any column with a business meaning can potentially change, and if there s one thing that we learned over the years in the relational world it s that it s a fatal mistake to give your keys meaning. If your users decide to change the business meaning, perhaps they want to add some digits or make the number alphanumeric, you need to make changes to your database in every single spot where you use that information. Anything that is used as a primary key in one table is virtually guaranteed to be used in other tables as a foreign key. What should be a simple change, adding a digit to your customer number, can be a huge maintenance nightmare. Yuck. In the relational database world, this OID strategy is referred to as employing surrogate keys. To give you an example, consider telephone numbers. Because phone numbers are unique many companies use them as keys for their customers. Although this sounds like a good idea, you re actually asking for trouble. I live near Toronto, Canada and because of the increased use of cellular phones, modems, and fax machines the local phone company was recently forced to divide the phone numbers of the 416 area code between 416 and 905. What s less work, changing the phone numbers in a few tables that had them as non key columns, or changing lots of tables that used them as either primary or foreign keys not to mention the changes needed to your indexes? Moral of the story OIDs should have no business meaning. 2.2 OID Uniqueness When assigning object IDs (OIDs) there are two main issues that you need to address: The level of uniqueness of the OID and how to calculate it. The importance of the first issue, uniqueness, isn t always obvious to developers who are new to object orientation. There are three levels of uniqueness that you need to consider: uniqueness within the class, uniqueness within the class hierarchy, and uniqueness across all classes. An OID should be unique within a class hierarchy, and ideally unique among all objects. For example, will the OID for a customer object be unique only for instances of customer, to people in general, or to all objects. Given the OID value will it be assigned to a customer object, an employee object, and an order object, will it be assigned to a customer but not an employee (because Customer and Employee are in the same class hierarchy), or will it only be assigned to a customer object and that s it. The real issue is one of polymorphism: It is probable that a customer object may one day become an employee object, but likely not an order object. To avoid this issue of reassigning OIDs when an object changes type, you at least want uniqueness at the class hierarchy level, although uniqueness across all classes completely avoids this issue. 2.3 Strategies for Assigning OIDs The second issue, that of determining new OIDs, can greatly affect the runtime efficiency of your application.
7 Using MAX() on an Integer Column In the past (Ambler, 1996) I suggested that one approach to assigning OIDs was to use the SQL MAX() function on an integer column being used as a primary key. The basic idea is that when you insert a new row into the table that you take the MAX() of that column, add one to it, and then use that as the value for your key. The problems with this approach is that you do a momentary table lock, although many databases are optimized for this approach, and that you don t have unique values for OIDs across all your objects, only for those stored within each table Maintaining a Key-Values Table There are two flavors of this approach, the first where you maintain a single row with a single integer column in which a counter value is stored. When you insert into any table you first lock and increment this value and use it as the OID value. The advantage of this approach is that you avoid locking the other tables when you invoke MAX() and that you have a unique value across all objects. The disadvantages are that this table becomes a bottleneck (although you can cache this value in memory if needed). and that you quickly run through OID values. The second flavor is to use a multi-row table where you have one row per table in your system, where each row has two columns, the first column is an identifier for the table name and the second is the integer value of the next key value for that table. Once again you avoid table locking with this approach but now have a greater range of OID values because each table now has it s own counter. Now you re back to losing uniqueness of OID values between objects and this table still potentially becomes a bottleneck (although you can cache these values in memory if needed) GUIDs/UUIDs Several years ago Digital came up with a strategy called UUIDs for determining generating unique key values based on hashing the value of the identification number of the Ethernet card within your computer and the current date and time, producing a 128-bit string that was guaranteed unique. For computers without Ethernet cards you could obtain a identification number stored online in a file. Microsoft has a similar strategy called GUIDs that also results in a 128-bit string. Both of these strategies work well, although both strategies are proprietary and do not run on all platforms. There is also the philosophical issue to deal with, although I don t think it s a big deal, of not having your persistence mechanism(s) assign OID values for you Proprietary Persistence Mechanism Features Some databases, for example Oracle, have built in features for generating unique values that can be used for OID values. Although these approaches work well, they are by definition proprietary and therefore out of your control. If you ever have to port to a new persistence mechanism, an event that is far more common and likely than your database/persistence community is willing to admit, then this can become a serious issue for you.
8 4 Scott s General Design Philosophy: Proprietary Approaches Will Always Burn You I can t be more emphatic about this: you really need to think before accepting a proprietary technology within your environment. Yes, there are always performance reasons, and often ease-of-development reasons, but never forget that you also need to worry about itty-bitty issues such as portability, reliability, scalability, enhancability, and maintainability. I ve seen a lot of organizations get themselves into serious trouble by using proprietary features that lock them into technologies that later prove to be insufficient for their futures needs. Later in this paper I ll discuss the evils of using stored procedures, amazingly enough still proprietary technology after all of these years The HIGH/LOW Approach To OIDs The basic idea is that instead of using a large integer for the OID, requiring you to go to a single source (and therefore a bottleneck) to obtain the OID, you reorganize your OID into two logical components: A HIGH value that you obtain from a single source and a LOW value that the application assigns itself. The value HIGH is obtained from a single row table in the database (or from a built in key value function for some databases) when the application first needs to create an OID. Because HIGH is obtained from a single source it is guaranteed to be unique. At this point the value for LOW is set at zero and is incremented every time an OID is needed for that user s session. For example, if the application that you re running requests a value for HIGH it will be assigned the value 1701 for HIGH, and all OIDs that the application assigns to objects will be combination of 1701 & 1, 1701 & 2, and so on. If my application requests a value for HIGH immediately after you it will given the value of 1702, and the OIDs that will be assigned to objects that I create will be 1702 &1, 1702 & 2, and so on. The advantage of this approach is that the single row table is no longer as big of a bottle neck, there is very little network traffic needed to get the value for an OID (one database hit per session), and OIDs can be assigned uniquely across all classes. In other words, this approach is as simple and efficient as you re ever going to get it. Yes, because it s possible that your value of LOW could be incremented to the maximum value that your design calls for, for example if LOW is four digits then the maximum value is 9999, therefore at this point you ll need to fetch a new value of HIGH and reset the value of LOW.
9 Implementing a HIGH/LOW OID Figure 1 presents one way to implement an OID class. The basic idea is that when a new persistent object is created it is assigned an OID which is created by the single instance of Object Factory. The sole responsibility of Object Factory is to create new OID objects. It does this by keeping track of the next HIGH and LOW values, having to fetch a HIGH value from the persistence mechanism (database) occasionally to do so. It creates an instance of OID based on the next values and returns it to be used as the unique OID for the new persistent object. The ascolumns method returns a collection of data items that can be saved to a relational database to represent the instance of OID. Take an OO approach to OIDs and encapsulate their behavior in a class. Figure 1. A class diagram showing a possible way to implement a HIGH/LOW OID. Figure 2 shows three of the possible strategies for how a HIGH/LOW OID might be implemented in your relational database. Neither strategy is ideal, each has its advantages and disadvantages, the important thing is that you choose one strategy and use it consistently for all tables, making your persistence layer (Ambler, 1998c) that much easier to develop. The first strategy uses a single integer number for the key, simplifying your key strategy but putting a fairly small upper limit on the value of your OIDs (the largest integer number your database handles). The second strategy alleviates the size problem, you store the OID as a string of an arbitrary size that you choose, but increases the overhead of your key by using a large string (many databases are optimized to use single large integers as the primary keys but are slower for strings). The third strategy uses a composite key for your OID, the disadvantages of composite keys are discussed later in this paper, potentially reducing the storage overhead of your keys (as compared to the second strategy). Figure 2. Mapping a HIGH/LOW OID to a relational table.
10 6 A fourth strategy, a combination of the second and third, involves hashing the OID object to a string. The basic idea is that you convert the OID into a collection of 8-bit numbers and then build a string from the numbers by first converting each number to a character and then concatenating the characters. For example, if your OID is built from a 32-bit HIGH number and an 8-bit LOW value then you would save them out as a 5-character string, the first four characters representing the high number (32/8 = 4) and the fifth representing the LOW value. Scott s Preferred Approach I typically use a 96-bit high number (often the combination of three 32-bit integers) for HIGH and a 32-bit integer for low. I then convert it to a 128-bit string taking the performance hit on using it as a key. The main disadvantage of this is that some databases have not yet been optimized for keys of fixed-length strings (instead they are optimized for Integers). This will change in time as developers demand support for more sophisticated approach to keys HIGH/LOW OIDs In a Distributed Environment As mentioned previously, OIDs must be unique. But how do you guarantee uniqueness in a distributed environment where a client may obtain the HIGH value for its OID from a number of servers? The answer is simple: the server machines must also have a strategy for obtaining unique HIGH values between themselves. There are several strategies to doing so. First, the servers could use their own internal HIGH/LOW approach, obtaining a HIGH value from a single source. Second, the servers could obtain a block of HIGH values from a centralized source, obtaining a new block when they run out HIGH/LOW OIDs In A Multi-Vendor Environment A related issue occurs when your organization uses persistence mechanisms produced by several vendors, a common occurrence in large organizations. Although several database vendors have strategies for producing surrogate keys, even in distribute environments, these strategies are typically applicable only for the products that they sell. The issue boils down to this: if the proprietary key value approach of Vendor A produces a HIGH value of 1701, and the proprietary key value approach of Vendor B also produces a HIGH value of 1701, then you re completely screwed. The implication is that you will need to roll your own strategy in such an environment, likely one of the strategies mentioned in the previous section. 2.4 Replication of Objects Replication is the issue of ensuring the information is kept up-to-date and synchronized when it is being stored and potentially updated at several physical locations. A primary consideration with the replication of data is the manner in which they are identified, and by having OIDs that are unique across all persistence mechanisms, regardless of vendor, ensures that you are able to determine uniquely identify an object no matter where and when it was created. There are significantly more issues involved with replication than just uniquely identifying objects, the point to be made is that OIDs are an enabler of replication.
11 7 3. The Basics of Mapping In this section I will describe some of the basic issues of mapping objects into relational databases. These issues are: Mapping attributes to columns Mapping classes to tables Implementing inheritance in an RDB Mapping several classes to a single table Mapping relationships One-to-one One-to-many Many-to-many Association vs. aggregation Same classes/tables, different relationships 3.1 Mapping Attributes To Columns The attribute of a class will map to zero or more columns in a relational database. Remember, not all attributes are persistent. For example, an Invoice class may have a grandtotal attribute that is used by instances for calculation purposes but that isn t saved to the database. Furthermore, because some attributes of an objects are objects Attributes map to columns. in their own right, a Customer object has an Address object as an attribute, sometimes a single OO attribute will map to several columns in the database (actually, chances are that the Address class will map to one or more tables in its own right). The important thing is that this is a recursive definition: At some point the attribute will be mapped to zero or more columns. 3.2 Mapping Classes To Tables Classes map to tables, although often not directly. Except for very simple databases, you will never have a one-to-one mapping of classes to tables. In this section we will explore three different strategies for implementing inheritance structures to a relational database and see an example where dissimilar classes map to one table Implementing Inheritance in a Relational Database By using OIDs to uniquely identify our objects in the database we greatly simplify our strategy for database keys (table columns that uniquely identify records) making it easier to implement inheritance, aggregation, and instance relationships. First let s consider inheritance, the relationship that throws in the most interesting twists when saving objects into a relational DB. The problem basically boils down to How do you organize the inherited attributes within the database? The way in which you answer this question can have a major impact on your system design. There are three fundamental solutions for mapping inheritance into a relational database: 1. Use one table for an entire class hierarchy. Map an entire class hierarchy into one table, where all the attributes of all the classes in the hierarchy are stored in it. The advantages of this approach are that it is simple polymorphism is supported when a person either changes roles or has multiple roles (i.e., the person is both a customer and an employee). Ad hoc reporting is also very easy with this
12 8 approach because all of the data you need about a person is found in one table. The disadvantages are that every time a new attribute is added anywhere in the class hierarchy a new attribute needs to be added to the table. This increases the coupling within the class hierarchy If a mistake is made when adding a single attribute it could affect all the classes within the hierarchy and not just the subclasses of whatever class got the new attribute. It also wastes a lot of space in the database. 2. Use one table per concrete class. Each table includes both the attributes and the inherited attributes of the class that it represents. The main advantage of this approach is that it is still fairly easy to do ad hoc reporting as all the data you need about a single class is stored in only one table. There are several disadvantages however. First, when we modify a class we need to modify its table and the table of any of its subclasses. For example if we were to add height and weight to the person class we would need to add it in all three of our tables, a lot of work. Second, whenever an object changes its role, perhaps we hire one of our customers, we need to copy the data into the appropriate table and assign it a new OID, once again a lot of work. Third, it is difficult to support multiple roles and still maintain data integrity (it s possible, just harder than it needs to be). 3. Use one table per class. Create one table per class, the attributes of which are the OID and the attributes that are specific to that class. The main advantage of this approach is that it conforms to object-oriented concepts the best. It supports polymorphism very well as you merely have records in the appropriate tables for each role that an object might have. It is also very easy to modify superclasses and add new subclasses as you merely need to modify/add one table. There are several disadvantages to this approach. First, there are many tables in the database, one for every class (plus tables to maintain relationships). Second, it takes longer to read and write data using this technique because you need to access multiple tables. This problem can be alleviated if you organize your database intelligently by putting each table within a class hierarchy on different physical disk-drive platters (this assumes that the disk-drive heads all operate independently). Third, ad hoc reporting on your database is difficult, unless you add views to simulate the desired tables. Let s consider an example. Figure 3 presents a UML (Rational, 1997) class diagram of a simple class hierarchy (the methods aren t shown) that I will map using each strategy, the resulting data models for which are shown in Figure 4. Notice how each strategy results in a different data model. Also notice how OIDs have been used for the keys. For the one table per class strategy the OID is used as both the primary key and as the foreign key to the Person table. Person {abstract} name phonenumber startdate Employee Customer customerid preferences Figure 3. A UML class diagram of a simple class hierarchy.
13 9 One Table Per Hierarchy Person OID name phonenumber customernumber preferences startdate objecttype One Table Per Concrete Class Customer OID name phonenumber customernumber preferences Employee OID name phonenumber startdate Customer OID (FK) customernumber preferences One Table Per Class Person OID name phonenumber objecttype is a is a Employee OID (FK) startdate Figure 4. Mapping the class hierarchy using each strategy. An interesting issue with the second mapping strategy, using one table per concrete class, is what do you do when you have someone who is both an employee and a customer 2? The basic issue is what table is the authorative source for the name and phone number of the person? This is something that you will need to decide, as well as rules for what to do when people (no longer) become an employee or customer, and then support it in your code. To understand the design trade offs between the three strategies, consider the simple change to our class hierarchy presented in Figure 5: an Executive class has been added which inherits from Employee. Figure 6 presents the updated data models. Notice how very little effort was required to update the one table per hierarchy strategy, although the obvious problem of wasted space in the database has increased. With the one table per concrete class strategy we only needed to add a new table, although the issue of how do we handle objects that either change their relationship with us (customers become employees) has now become more complex because we ve added the issue of promoting employees to become executives. With the third mapping strategy, mapping a single class to a single table, we needed to add a new table, one that included only the new attributes of Executive. The disadvantage of this approach is that it requires several database accesses to work with instances of Executive. The point to go away with is that none of the approaches are perfect, that each has its strengths and weaknesses (which are summarized in Table 1). 2 The use of the relationship is a in Figure 4 is not inheritance in this case, implied by the fact that the relationship is not mandatory. Sometimes an employee is a customer, sometimes they are not. Yet another example of the object/relational impedance mismatch.
14 10 Person {abstract} name phonenumber startdate Employee Customer customerid preferences bonus Executive Figure 5. Extending the hierarchy.
15 11 One Table Per Hierarchy Person OID name phonenumber customernumber preferences startdate bonus objecttype One Table Per Concrete Class Customer OID name phonenumber customernumber preferences Employee OID name phonenumber startdate Executive OID name phonenumber startdate bonus Customer OID (FK) customernumber preferences One Table Per Class Person OID name phonenumber objecttype is a is a Employee OID (FK) startdate is a Executive OID (FK) bonus Figure 6. Extending the data models. Factors to Consider One table per hierarchy One table per concrete class One table per class Ad-hoc reporting Simple Medium Medium/Difficult Ease of implementation Simple Medium Difficult Ease of data access Simple Simple Medium/Simple Coupling Very high High Low Speed of data access Fast Fast Medium/Fast Support for polymorphism Medium Low High Table 1. Comparing the approaches to mapping inheritance Mapping Several Classes To One Table Figure 7 shows a class diagram of the implementation of an address that uses two classes, Address and Zip Code. The Zip Code class was created to encapsulate the logic of validating a zip code number and formatting it appropriate for mailing labels. For example is the state correct (in the U.S. the first two digits of a zip code indicate the state) and hyphens should be inserted at appropriate places when the zip code is output (the U.S. post office recently introduced a long version of a zip code with three sections to
16 12 it). The bottom line is that the Zip Code class encapsulates cohesive behavior that is relevant to zip codes. Address -street : String -unitnumber : String -city : String -state : String +labelstring() : String has ZipCode -number : Integer +labelstring() : String +validate() : Boolean Figure 7. A UML class diagram representing a simple OO implementation of an address. In a relational database, however, the behavior implemented by the Zip Code class isn t relevant, therefore a zip code can map to a single column in the Address table. Figure 8 shows the data model for Address for this particular situation (we ll revisit this example later in the paper for an alternative data model design based on new requirements). The lesson to be learned is that sometimes two dissimilar classes will map to one table. This occurs because class diagrams take a greater scope than data models they show data and behavior whereas data models only show data. Address addressoid street unitnumber city state zipcode Figure 8. A data model showing a possible implementation for an address. 3.3 Mapping Relationships Not only do we need to map objects into the database, we also need to map the relationships that the object is involved with so they can be restored at a later date. There are two types of relationship that an object can be involved with: association and aggregation. To map these relationships effectively we must understand the difference between them, how to implement relationships generally, and how to implement many-to-many relationships specifically The Difference Between Association and Aggregation From a database perspective the only difference between association and aggregation relationships is how tightly the objects are bound to each other. With aggregation anything that you do to the whole in the database you almost always need to do to the parts, whereas with association that isn t the case.
17 13 parked at Airport Airplane Wing n n Figure 9. The difference between instance and aggregation relationships. In Figure 9 (Ambler, 1998a) we see three classes, two of which have a simple association between them and two which share an aggregation relationship. From a database point of view aggregation and association are different in the fact that with aggregation you usually want to read in the part when you read in the whole, whereas with an association it isn t always as obvious what you need to do. The same goes for saving objects to the database and deleting objects from the database. Granted this is usually specific to the business domain, but this rule of thumb seems to hold up in most circumstances. The differences between aggregation and association are discussed in further detail in my second book, Building Object Applications That Work (Ambler, 1998a) Implementing Relationships in Relational Databases Relationships in relational databases are maintained through the use of foreign keys. A foreign key is a data attribute(s) that appears in one table that may be part of or is coincidental with the key of another table. Foreign keys allow you to relate a record in one table with a record in another. To implement oneto-one and one-to-many relationships you merely have to include the key of one table in the other table. Let s look at an example. Employee Position positionoid title salaryrange works at employeeoid positionoid (FK) name salary startdate assigned to Task taskoid employeeoid(fk) description Figure 10. Implementing relationships in a relational database.
18 14 In Figure 10 3 (Ambler, 1998a) we see three tables, their keys (OIDs of course), and the foreign keys used to implement the relationships between them. First, we have a one-to-one relationship between Position and Employee. To implement this relationship we added the attribute positionoid, which is the key of Position, although we could just as easily have added a foreign key called employeeoid in Position instead. Second, we implement the many-to-one relationship (also referred to as a one-to-many relationship) between Employee and Task using the same sort of approach, the only difference being that we had to put the foreign key in Task because it was on the many side of the relationship Implementing Many-To-Many Relationships To implement many-to-many relationships we need to introduce the concept of an associative table, a table whose sole purpose is to maintain the relationship between two or more tables in a relational database. In Figure 11 (Ambler, 1998a) we see that there is a many-to-many relationship between customers and accounts. In Figure 12 (Ambler, 1998a) we see how to use an associative table to implement a many-to-many relationship. In relational databases the attributes contained in an associative table are traditionally the combination of the keys in the tables involved in the relationship. It has been my experience, however, that it is easier to implement associative tables if you treat them as just another type of table You assign them their own key field, in our case OID, and then add the necessary foreign keys to maintain the relationship. Customer Account customerid preferences accesses 1..n 1..n balance accountnumber Figure 11. Two classes with a many-to-many relationship between them. The advantage of this is that all tables are treated the same by your persistence layer, simplifying its implementation. Another advantage is one of run-time efficiency: some relational databases have problems joining tables that have many attributes in their keys. There is also the possibility that one or more columns may be added to the Accesses table to represent the security access rights for the customer on the account. Perhaps a given customer can deposit money into an account, but not withdraw, whereas another customer has full access to the account. Customer customeroid preferences customerid Accesses OID customeroid (FK) accountoid (FK) Account accountoid accountnumber balance Figure 12. Implementing a many-to-many relationship in a relational database. 3 All data models in this paper are shown using the Data Structure Diagram notation from the mid-1980s. All class models are shown using the Unified Modeling Language (UML). Please refer to my second book, Building Object Applications That Work (Ambler, 1998a), for an explanation of each notation.
19 The Same Classes/Tables, Different Relationships Sometimes you can have a direct mapping between classes in your object application to tables in your relational database, yet the relationships between the classes/tables aren t the same. For example, Figure 13 shows an alternative implementation of the data model of Figure 8. In this case your organization has decided to purchase a list of all the zip codes in the countries that you do business in so that you can increase the quality of your address data. Unlike in the class diagram of Figure 7, which had a one-to-one relationship between the Address class and the Zip Code class, Figure 13 shows a many-to-one relationship. Assuming both models are correct, and for the purpose of this discussion they are, how can this be? The answer is that the needs are different. Address addressoid street unitnumber city state zipcodeoid (FK) has a ZipCode zipcodeoid zipnumber Figure 13. A data model showing an alternate implementation for an address. The class diagram in Figure 7 shows that the OO application only needs a Zip Code class to encapsulate the validation rules of a zip code is it in the right format, is it in the right state it does not care about the fact that there are several addresses with the same zip code. There were no business requirements stating that a zip code has many addresses in it. The data model in Figure 13 shows that it is possible to have several addresses in the same zip code, which is an accurate way to model the data. Figure 13 also shows that sometimes you ll have an address with a zip code that isn t in the list that you bought (depending on the country you live in, even the post office does not have an accurate list of all zip codes). The zip code might be correct, it just isn t in your official list of zip codes. You might decide to have insertion triggers in your database to ensure that you don t insert an address without a proper zip code (perhaps if the zip code does not exist in the table you automatically add it to the list). Scott's Soapbox Data Models Don't Always Reflect Actual Requirements The differences between the class model of Figure 7 and the data model of Figure 13 reveal a fundamental flaw in the approach taken by many data models. Don't get me wrong, the data model is in fact accurate, it just that it doesn't reflect the actual requirements of the organization that it was being modeled for. What is the impact of this mistake? First, the code written to support this data model, something that few data modelers take into consideration (very often they don't write any code at all) is much more complex than the code that would be written to support the class model. The association modeled in the data model is much more complex than that of the class model: it is bi-directional and optional. Second, there is now a difference (likely unbeknownst to the data modelers) between the software being built and the actual needs of the users of that software. Albeit this is a small difference, the example is very simple for the sake of discussion, but any difference will result in a greater training burden and cost of support for your organization. Yes, you could rework your class diagram to take advantage of the fact that you now have this official list of zip codes, perhaps to do analysis of where your customers live, but until you have an actual requirement to do so you shouldn t perhaps your users don t need such a thing.
20 16 4. Concurrency, Objects, and Row Locking For this white paper concurrency deals with the issues involved with allowing multiple people simultaneous access to the same record in your relational database. Because it is possible, if you allow it, for several users to access the same database records, effectively the same objects, you need to determine a control strategy for allowing this. The control mechanism used by relational databases is locking, and in particular row locking. 4.1 Pessimistic Vs. Optimistic Locking There are two main approaches to row locking: pessimistic and optimistic. 1. Pessimistic locking. An approach to concurrency in which an item is locked in the persistence mechanism for the entire time that it is in memory. For example, when a customer object is edited a lock is placed on the object in the persistence mechanism, the object is brought into memory and edited, and then eventually the object is written back to the persistence mechanism and the object is unlocked. This approach guarantees that an item won t be updated in the persistence mechanism while the item is in memory, but at the same time is disallows others to work with it while someone else does. Pessimistic locking is ideal for batch jobs that need to ensure consistency in the data that they write. 2. Optimistic locking. An approach to concurrency in which an item is locked in the persistence mechanism only for the time that it is accessed in the persistence mechanism. For example, if a customer object is edited a lock is placed on it in the persistence mechanism for the time that it takes to read it in memory and then it is immediately removed. The object is edited and then when it needs to be saved it is locked again, written out, then unlocked. This approach allows many people to work with an object simultaneously, but also presents the opportunity for people to overwrite the work of others. Optimistic locking is best for online processing. Yes with optimistic locking you have an overhead of determining whether or not the record has been updated by someone else when you go to save it. This can be accomplished via the use of a common timestamp field in all tables: When you read a record you read in the timestamp. When you go to write the record you compare the timestamp in memory to the one in the database, if they re the same then you update the record (including the timestamp to the current time). If they re different the someone else has updated the record and you can t overwrite it (therefore displaying a message to the user). 5. Stored Procedures A stored procedure is basically a function that runs on a relational database server. Although SQL code is usually a major component of a stored procedure most database vendors have their own proprietary programming language, each with its strengths and weaknesses. A stored procedure typically runs some SQL code, potentially massages the data, and then hands back a response in the form of zero or more records or as a database error message. Stored procedures are a very powerful feature of modern relational databases. When mapping objects to relational databases there are two situations where using stored procedures make sense. First is when you re building a quick and dirty prototype that you intend to throw away, assuming that you don t have a solid persistence layer (Ambler, 1998c) already built, then this is most
CRC Modeling: Bridging the Communication Gap Between Developers and Users
CRC Modeling: Bridging the Communication Gap Between Developers and Users An AmbySoft Inc. White Paper Scott W. Ambler Software Process Mentor AmbySoft Inc. Material for this paper has be excerpted from:More information
Agile Database Techniques: Effective Strategies for the Agile Software Developer HDT822 Four Days
Four Days Prerequisites Students should have experience designing databases and data warehouses. Knowledge of Agile design techniques is helpful. Who Should Attend This course is targeted at database designers,More information
Introducing DocumentDB
David Chappell Introducing DocumentDB A NoSQL Database for Microsoft Azure Sponsored by Microsoft Corporation Copyright 2014 Chappell & Associates Contents Why DocumentDB?... 3 The DocumentDB Data Model...More information
Agile Database Techniques. Effective Strategies for the Agile Software Developer
Brochure More information from http://www.researchandmarkets.com/reports/2249917/ Agile Database Techniques. Effective Strategies for the Agile Software Developer Description: "I wish I had a book likeMore information
Agile Techniques for Object Databases
db4o The Open Source Object Database Java and.net Agile Techniques for Object Databases By Scott Ambler 1 Modern software processes such as Rational Unified Process (RUP), Extreme Programming (XP), andMore information
Database Design Basics
Database Design Basics Table of Contents SOME DATABASE TERMS TO KNOW... 1 WHAT IS GOOD DATABASE DESIGN?... 2 THE DESIGN PROCESS... 2 DETERMINING THE PURPOSE OF YOUR DATABASE... 3 FINDING AND ORGANIZINGMore information
The Design of a Robust Persistence Layer For Relational Databases
The Design of a Robust Persistence Layer For Relational Databases Scott W. Ambler Senior Consultant, Ambysoft Inc. www.ambysoft.com/scottambler.html http://www.ambysoft.com/downloads/persistencelayer.pdfMore information
Database design basics
Microsoft Office Access Database design basics Applies to: Microsoft Office Access 2007 A properly designed database provides you with access to up-to-date, accurate information. Because a correct designMore information
PostgreSQL Concurrency Issues
PostgreSQL Concurrency Issues 1 PostgreSQL Concurrency Issues Tom Lane Red Hat Database Group Red Hat, Inc. PostgreSQL Concurrency Issues 2 Introduction What I want to tell you about today: How PostgreSQLMore information
Once the schema has been designed, it can be implemented in the RDBMS.
2. Creating a database Designing the database schema... 1 Representing Classes, Attributes and Objects... 2 Data types... 5 Additional constraints... 6 Choosing the right fields... 7 Implementing a tableMore information
Data Modeling Basics
Information Technology Standard Commonwealth of Pennsylvania Governor's Office of Administration/Office for Information Technology STD Number: STD-INF003B STD Title: Data Modeling Basics Issued by: DeputyMore information
A Shift in the World of Business Intelligence
Search Powered Business Analytics, the smartest way to discover your data A Shift in the World of Business Intelligence Comparison of CXAIR to Traditional BI Technologies A CXAIR White Paper www.connexica.comMore information
Getting started with API testing
Technical white paper Getting started with API testing Test all layers of your composite applications, not just the GUI Table of contents Executive summary... 3 Introduction... 3 Who should read this document?...More information
Cache Database: Introduction to a New Generation Database
Cache Database: Introduction to a New Generation Database Amrita Bhatnagar Department of Computer Science and Engineering, Birla Institute of Technology, A 7, Sector 1, Noida 201301 UP firstname.lastname@example.com information
Unified Modeling Language (UML) for Database Systems and Computer Applications
Unified Modeling Language (UML) for Database Systems and Computer Applications Sunguk Lee * Research Institute of Industrial Science and Technology Pohang, Korea firstname.lastname@example.com *Correspondent Author:More information
Object Oriented System Development with VB.NET
Chapter 1 Object Oriented System Development with Objectives In this chapter, you will: Learn about OO development and Understand object-oriented concepts Recognize the benefits of OO development PreviewMore information
Database Modelling in UML
Database Modelling in UML By Geoffrey Sparks, email@example.com : http://www.sparxsystems.com.au Originally published in Methods & Tools e-newsletter : http://www.martinig.ch/mt/index.html IntroductionMore information
Object Oriented Design with UML and Java. PART XVIII: Database Technology
Object Oriented Design with UML and Java PART XVIII: Database Technology Copyright David Leberknight & Ron LeMaster. Version 2 What is a Database? Computerized record-keeping system. Collection of storedMore information
Google Lead Generation For Attorneys - Leverage The Power Of Adwords To Grow Your Law Business FAST. The Foundation of Google AdWords
Google Lead Generation For Attorneys - Leverage The Power Of Adwords To Grow Your Law Business FAST You re about to discover the secrets of fast legal practice success with Google AdWords. Google AdWordsMore information
Net Integrator Firewall
Net Integration Technologies, Inc. http://www.net itech.com Net Integrator Firewall Technical Overview Version 1.00 TABLE OF CONTENTS 1 Introduction...1 2 Firewall Architecture...2 2.1 The Life of a Packet...2More information
The structure of accounting systems: how to store accounts Lincoln Stoller, Ph.D.
The structure of accounting systems: how to store accounts Lincoln Stoller, Ph.D. balances In my most recent article I considered the simplest accounting system consisting of a single file of general ledgerMore information
InfiniteGraph: The Distributed Graph Database
A Performance and Distributed Performance Benchmark of InfiniteGraph and a Leading Open Source Graph Database Using Synthetic Data Objectivity, Inc. 640 West California Ave. Suite 240 Sunnyvale, CA 94086More information
An introduction. L 16, Week 9, November 2009. 2COM0085 Computer Science Development Exercise. 2COM0086 Information Technology Development Exercise
2COM0085 Computer Science Development Exercise 2COM0086 Information Technology Development Exercise Object-relational mapping: An introduction L 16, Week 9, November 2009 1 Object-relational mapping (ORM):More information
Tutorial on Relational Database Design
Tutorial on Relational Database Design Introduction Relational database was proposed by Edgar Codd (of IBM Research) around 1969. It has since become the dominant database model for commercial applicationsMore information
Database Management System Dr. S. Srinath Department of Computer Science & Engineering Indian Institute of Technology, Madras Lecture No.
Database Management System Dr. S. Srinath Department of Computer Science & Engineering Indian Institute of Technology, Madras Lecture No. # 7 ER Model to Relational Mapping Hello and welcome to the nextMore information
Google Lead Generation for Attorneys
1 Google Lead Generation For Attorneys Leverage The Power Of AdWords To Grow Your Law Business FAST You re about to discover the secrets of fast legal practice success with Google AdWords. Google AdWordsMore information
Differences in Programming: Btrieve s Way of Thinking With ODBC s Spice
Differences in Programming: Btrieve s Way of Thinking With ODBC s Spice Revision 2 February 2002 Pervasive Software Inc. Pervasive Software Inc. 12365 Riata Trace Parkway II Austin, Texas 78727 PublicMore information
Application Of Business Intelligence In Agriculture 2020 System to Improve Efficiency And Support Decision Making in Investments.
Application Of Business Intelligence In Agriculture 2020 System to Improve Efficiency And Support Decision Making in Investments Anuraj Gupta Department of Electronics and Communication Oriental InstituteMore information
Microsoft Access Basics
Microsoft Access Basics 2006 ipic Development Group, LLC Authored by James D Ballotti Microsoft, Access, Excel, Word, and Office are registered trademarks of the Microsoft Corporation Version 1 - RevisionMore information
Physical Design. Meeting the needs of the users is the gold standard against which we measure our success in creating a database.
Physical Design Physical Database Design (Defined): Process of producing a description of the implementation of the database on secondary storage; it describes the base relations, file organizations, andMore information
The Phases of an Object-Oriented Application
The Phases of an Object-Oriented Application Reprinted from the Feb 1992 issue of The Smalltalk Report Vol. 1, No. 5 By: Rebecca J. Wirfs-Brock There is never enough time to get it absolutely, perfectlyMore information
Realization of Inventory Databases and Object-Relational Mapping for the Common Information Model
Realization of Inventory Databases and Object-Relational Mapping for the Common Information Model Department of Physics and Technology, University of Bergen. November 8, 2011 Systems and VirtualizationMore information
Perform-Tools. Powering your performance
Perform-Tools Powering your performance Perform-Tools With Perform-Tools, optimizing Microsoft Dynamics products on a SQL Server platform never was this easy. They are a fully tested and supported setMore information
Testing, What is it Good For? Absolutely Everything!
Testing, What is it Good For? Absolutely Everything! An overview of software testing and why it s an essential step in building a good product Beth Schechner Elementool The content of this ebook is providedMore information
Copyright 2010 You have giveaway rights to this report. Feel free to share.
Article Marketing Magic Copyright 2010 You have giveaway rights to this report. Feel free to share. Table of Contents What Is Article Marketing?...3 The History of Article Marketing...7 Article MarketingMore information
Agile Business Suite: a 4GL environment for.net developers DEVELOPMENT, MAINTENANCE AND DEPLOYMENT OF LARGE, COMPLEX BACK-OFFICE APPLICATIONS
Agile Business Suite: a 4GL environment for.net developers DEVELOPMENT, MAINTENANCE AND DEPLOYMENT OF LARGE, COMPLEX BACK-OFFICE APPLICATIONS In order to ease the burden of application lifecycle management,More information
Using the Information Engineering Notation.
Using the Information Engineering Notation. Scott Lurton Specialist Master email@example.com 1 I wrote this white paper because I was becoming more and more concerned about the loss of time caused byMore information
UML Tutorial: Collaboration Diagrams
UML Tutorial: Collaboration Diagrams Robert C. Martin Engineering Notebook Column Nov/Dec, 97 In this column we will explore UML collaboration diagrams. We will investigate how they are drawn, how theyMore information
Planning a Responsive Website
Planning a Responsive Website Planning a website is important for both web designers and website owners. Planning your website before you start building it can save you time, keep your site code more accurateMore information
Spreadsheet vs. Database: Hidden cost of a spreadsheet solution. Andrew Powell Paisley Software Solutions, Inc.
Spreadsheet vs. Database: Hidden cost of a spreadsheet solution Andrew Powell Paisley Software Solutions, Inc. Reading this could save you 25% of your salary overhead! Today more than ever, companies employMore information
5Get rid of hackers and viruses for
Reprint from TechWorld /2007 TEChWoRLd ISSuE 2007 ThEBIG: 5 FIREWaLLS TEChWoRLd ISSuE 2007 ThEBIG: 5 FIREWaLLS TEChWoRLd ISSuE 2007 ThEBIG: 5 FIREWaLLS # # # Load balancing is basically a simple task whereMore information
Lag Sucks! R.J. Lorimer Director of Platform Engineering Electrotank, Inc. Robert Greene Vice President of Technology Versant Corporation
Lag Sucks! Making Online Gaming Faster with NoSQL (and without Breaking the Bank) R.J. Lorimer Director of Platform Engineering Electrotank, Inc. Robert Greene Vice President of Technology Versant CorporationMore information
Performance Comparison of Persistence Frameworks
Performance Comparison of Persistence Frameworks Sabu M. Thampi * Asst. Prof., Department of CSE L.B.S College of Engineering Kasaragod-671542 Kerala, India email@example.com Ashwin A.K S8, DepartmentMore information
Performance in the Infragistics WebDataGrid for Microsoft ASP.NET AJAX. Contents. Performance and User Experience... 2
Performance in the Infragistics WebDataGrid for Microsoft ASP.NET AJAX An Infragistics Whitepaper Contents Performance and User Experience... 2 Exceptional Performance Best Practices... 2 Testing the WebDataGrid...More information
Software Documentation Guidelines
Software Documentation Guidelines In addition to a working program and its source code, you must also author the documents discussed below to gain full credit for the programming project. The fundamentalMore information
n Assignment 4 n Due Thursday 2/19 n Business paper draft n Due Tuesday 2/24 n Database Assignment 2 posted n Due Thursday 2/26
Class Announcements TIM 50 - Business Information Systems Lecture 14 Instructor: John Musacchio UC Santa Cruz n Assignment 4 n Due Thursday 2/19 n Business paper draft n Due Tuesday 2/24 n Database AssignmentMore information
Object Oriented Design
Object Oriented Design Kenneth M. Anderson Lecture 20 CSCI 5828: Foundations of Software Engineering OO Design 1 Object-Oriented Design Traditional procedural systems separate data and procedures, andMore information
Data and Business Systems
Data and Business Systems Dr J A Briginshaw 21 May 2008 Silhouette Solutions Limited www.silhouettesolutions.com email@example.com Abstract We discuss the problems businesses typicallyMore information
Guide for Local Business Google Pay Per Click Marketing!
Guide for Local Business Google Pay Per Click Marketing! Guide for Google Pay Per Click Marketing - Leverage The Power Of Adwords To Grow Your Business FAST You re about to discover the secrets of fastMore information
Windows Server Performance Monitoring
Spot server problems before they are noticed The system s really slow today! How often have you heard that? Finding the solution isn t so easy. The obvious questions to ask are why is it running slowlyMore information
Email Marketing Methods
Email Marketing Methods Brought to You By PLR-MRR-Products.com Buy PLR, MRR or Resale Products through Membership or Direct Purchase Shopping Cart. You are also welcome to visit and download from our freeMore information
I-Motion SQL Server admin concerns
I-Motion SQL Server admin concerns I-Motion SQL Server admin concerns Version Date Author Comments 4 2014-04-29 Rebrand 3 2011-07-12 Vincent MORIAUX Add Maintenance Plan tutorial appendix Add RecommendedMore information
Developing a Backup Strategy for Hybrid Physical and Virtual Infrastructures
Virtualization Backup and Recovery Solutions for the SMB Market The Essentials Series Developing a Backup Strategy for Hybrid Physical and Virtual Infrastructures sponsored by Introduction to RealtimeMore information
7 Secrets To Websites That Sell. By Alex Nelson
7 Secrets To Websites That Sell By Alex Nelson Website Secret #1 Create a Direct Response Website Did you know there are two different types of websites? It s true. There are branding websites and thereMore information
Club Accounts. 2011 Question 6.
Club Accounts. 2011 Question 6. Anyone familiar with Farm Accounts or Service Firms (notes for both topics are back on the webpage you found this on), will have no trouble with Club Accounts. EssentiallyMore information
Database Design Considerations Designing a database requires an understanding of both the business functions you want to model and the database concepts and features used to represent those business functions.More information
The first program: Little Crab
CHAPTER 2 The first program: Little Crab topics: concepts: writing code: movement, turning, reacting to the screen edges source code, method call, parameter, sequence, if-statement In the previous chapter,More information
Dynamics CRM for Outlook Basics
Dynamics CRM for Outlook Basics Microsoft Dynamics CRM April, 2015 Contents Welcome to the CRM for Outlook Basics guide... 1 Meet CRM for Outlook.... 2 A new, but comfortably familiar face................................................................More information
Migration Manager v6. User Guide. Version 188.8.131.52
Migration Manager v6 User Guide Version 18.104.22.168 Revision 1. February 2013 Content Introduction... 3 Requirements... 3 Installation and license... 4 Basic Imports... 4 Workspace... 4 1. Menu... 4 2. Explorer...More information
An Object-Oriented Architecture for Business-To-Consumer Electronic Commerce On The Internet
An Object-Oriented Architecture for Business-To-Consumer Electronic Commerce On The Internet A White Paper Scott W. Ambler Software Process Mentor Material for this White Paper has been taken from BuildingMore information
Java Application Developer Certificate Program Competencies
Java Application Developer Certificate Program Competencies After completing the following units, you will be able to: Basic Programming Logic Explain the steps involved in the program development cycleMore information
Product Review: James F. Koopmann Pine Horse, Inc. Quest Software s Foglight Performance Analysis for Oracle
Product Review: James F. Koopmann Pine Horse, Inc. Quest Software s Foglight Performance Analysis for Oracle Introduction I ve always been interested and intrigued by the processes DBAs use to monitorMore information
THE BENEFITS AND RISKS OF CLOUD PLATFORMS A GUIDE FOR BUSINESS LEADERS DAVID CHAPPELL JANUARY 2011 SPONSORED BY MICROSOFT CORPORATION Cloud platforms are a fundamental part of the move to cloud computing.More information
Single Business Template Key to ROI
Paper 118-25 Warehousing Design Issues for ERP Systems Mark Moorman, SAS Institute, Cary, NC ABSTRACT As many organizations begin to go to production with large Enterprise Resource Planning (ERP) systems,More information
Five Reasons to Choose a Software Load Balancer Nginx, Inc. 2014 For more information please visit nginx.com
Five Reasons to Choose a Software Load Balancer 1 Five Reasons to Choose a Software Load Balancer O nce upon a time, load balancing in most IT architectures was heavily dependent on hardware but that sMore information
SUPPLY CHAIN FINANCE. Extracting value from the supplier tail. A Purchasing Insight report in collaboration with Invapay
SUPPLY CHAIN FINANCE Extracting value from the supplier tail A Purchasing Insight report in collaboration with Invapay Supply Chain Finance and Working Capital Management are important tools for any businessMore information
Microsoft Access is an outstanding environment for both database users and professional. Introduction to Microsoft Access and Programming SESSION
539752 ch01.qxd 9/9/03 11:38 PM Page 5 SESSION 1 Introduction to Microsoft Access and Programming Session Checklist Understanding what programming is Using the Visual Basic language Programming for theMore information
III Big Data Technologies
III Big Data Technologies Today, new technologies make it possible to realize value from Big Data. Big data technologies can replace highly customized, expensive legacy systems with a standard solutionMore information
2 The first program: Little Crab
2 The first program: Little Crab topics: concepts: writing code: movement, turning, reacting to the screen edges source code, method call, parameter, sequence, if statement In the previous chapter, weMore information
How to off-load costly, redundant telecom administrative changes to your help desk.
White Paper WHITE PAPER How to off-load costly, redundant telecom administrative changes to your help desk. REDUCE COST AND IMPROVE SERVICE LEVELS BY ENABLING HELP DESK AGENTS TO EASILY AND IMMEDIATELYMore information
XXI. Object-Oriented Database Design
XXI. Object-Oriented Database Design Object-Oriented Database Management Systems (OODBMS) Distributed Information Systems and CORBA Designing Data Management Classes The Persistent Object Approach TheMore information
Object Oriented Databases. OOAD Fall 2012 Arjun Gopalakrishna Bhavya Udayashankar
Object Oriented Databases OOAD Fall 2012 Arjun Gopalakrishna Bhavya Udayashankar Executive Summary The presentation on Object Oriented Databases gives a basic introduction to the concepts governing OODBsMore information
SELLING SHAREPOINT ENGAGEMENTS IN THE CLOUD ERA A GUIDE FOR MICROSOFT SI PARTNERS Sponsored by Microsoft Corporation 1/ Selling SharePoint Online 2/ Selling SharePoint Farms on Windows Azure 3/ SellingMore information
Practical Cassandra. Vitalii Tymchyshyn firstname.lastname@example.com @tivv00
Practical Cassandra NoSQL key-value vs RDBMS why and when Cassandra architecture Cassandra data model Life without joins or HDD space is cheap today Hardware requirements & deployment hints Vitalii TymchyshynMore information
The question is what kind of VoIP do you want? What are the tradeoffs today?
Selecting a Voice Solution Hosted VoIP vs. PBX VoIP Contents Introduction The Traditional Solution Why VoIP? The Primary Tradeoffs Today Hosted VoIP Today s PBX Latest Features of VoIP Managing Costs WhatMore information
Controlling and Managing Security with Performance Tools
Security Management Tactics for the Network Administrator The Essentials Series Controlling and Managing Security with Performance Tools sponsored by Co ntrolling and Managing Security with PerformanceMore information
API Architecture. for the Data Interoperability at OSU initiative
API Architecture for the Data Interoperability at OSU initiative Introduction Principles and Standards OSU s current approach to data interoperability consists of low level access and custom data modelsMore information
Case studies: Outline. Requirement Engineering. Case Study: Automated Banking System. UML and Case Studies ITNP090 - Object Oriented Software Design
I. Automated Banking System Case studies: Outline Requirements Engineering: OO and incremental software development 1. case study: withdraw money a. use cases b. identifying class/object (class diagram)More information
Multi-Factor Authentication
Making the Most of Multi-Factor Authentication Introduction The news stories are commonplace: Hackers steal or break passwords and gain access to a company s data, often causing huge financial losses toMore information
UML FOR OBJECTIVE-C. Excel Software www.excelsoftware.com
UML FOR OBJECTIVE-C Excel Software www.excelsoftware.com Objective-C is a popular programming language for Mac OS X computers. The Unified Modeling Language (UML) is the industry standard notation forMore information
Security Testing. The Magazine for Professional Testers. June, 2009
6 June, 2009 The Magazine for Professional Testers ISSN 1866-5705 www.testingexperience.com free digital version print version 8,00 printed in Germany Security Testing istockphoto/alexandru_lamba istockphoto.com/kutaytanirMore information
What is Data Virtualization? Rick F. van der Lans, R20/Consultancy
What is Data Virtualization? by Rick F. van der Lans, R20/Consultancy August 2011 Introduction Data virtualization is receiving more and more attention in the IT industry, especially from those interestedMore information
In-memory Tables Technology overview and solutions
In-memory Tables Technology overview and solutions My mainframe is my business. My business relies on MIPS. Verna Bartlett Head of Marketing Gary Weinhold Systems Analyst Agenda Introduction to in-memoryMore information
Component Based Rapid OPC Application Development Platform
Component Based Rapid OPC Application Development Platform Jouni Aro Prosys PMS Ltd, Tekniikantie 21 C, FIN-02150 Espoo, Finland Tel: +358 (0)9 2517 5401, Fax: +358 (0) 9 2517 5402, E-mail: firstname.lastname@example.com,More information
Mike: Alright welcome to episode three of Server Talk, I m here with Alexey. I m Mike. Alexey, how are things been going, man?
Mike: Alright welcome to episode three of Server Talk, I m here with Alexey. I m Mike. Alexey, how are things been going, man? Alexey: They re doing pretty good. Yeah, I don t know, we ve launched twoMore information
Internet-based remote support for help desks
Internet-based remote support for help desks White Paper Published: October 2005 Contents Introduction...1 Advantages of Internet-based Remote Support...1 Reduced Support Costs through Increased Productivity...2More information
What is Data Virtualization?
What is Data Virtualization? Rick F. van der Lans Data virtualization is receiving more and more attention in the IT industry, especially from those interested in data management and business intelligence.More information
The Ultimate Small Business Guide To Setting Up A Work From Home Or Remote Network Access System For Your Staff
The Ultimate Small Business Guide To Setting Up A Work From Home Or Remote Network Access System For Your Staff Critical Facts And Insider Secrets Every Business Owner Must Know Before Installing A VirtualMore information
Data Warehouse and Business Intelligence Testing: Challenges, Best Practices & the Solution
Warehouse and Business Intelligence : Challenges, Best Practices & the Solution Prepared by datagaps http://www.datagaps.com http://www.youtube.com/datagaps http://www.twitter.com/datagaps Contact firstname.lastname@example.com information
Web Contents for Database Design Book
Web Contents for Database Design Book Link to the Authors Web Site The Perpetual Technologies web site, http://www.perptech.com, contains information about relational database technology, with specializationMore information
WHITE PAPER. Data Center Fabrics. Why the Right Choice is so Important to Your Business
WHITE PAPER Data Center Fabrics Why the Right Choice is so Important to Your Business Introduction Data center fabrics are emerging as the preferred architecture for next-generation virtualized data centers,More information
David Chappell OPERATIONAL SCENARIOS USING THE MICROSOFT DATA PLATFORM A GUIDE FOR IT LEADERS Sponsored by Microsoft Corporation Copyright 2016 Chappell & Associates Contents Microsoft s Data Platform:More information
Guide to Trading GUIDE TO TRADING
GUIDE TO TRADING 1 Table of contents THE GUIDE...3 INTRODUCTION...4 GETTING STARTED...8 HOW TO TRADE... 12 LADDER OPTION...20 ABOUT US...24 BASIC GLOSSARY...25 2 The Guide Dear client/investor We welcomeMore information
Using Object Database db4o as Storage Provider in Voldemort
Using Object Database db4o as Storage Provider in Voldemort by German Viscuso db4objects (a division of Versant Corporation) September 2010 Abstract: In this article I will show you howMore information
The. Essential. Guide. to an NDS-to- Active Directory Migration. By David Chernicoff. sponsored by. March 2010 1
Essential The Guide to an NDS-to- Active Directory Migration By David Chernicoff sponsored by March 2010 1 W ith the release of Windows Server 2008 and the latest iteration of Active Directory, many enterpriseMore information
This document is provided "as-is". Information and views expressed in this document, including URLs and other Internet Web site references, may
This document is provided "as-is". Information and views expressed in this document, including URLs and other Internet Web site references, may change without notice. Some examples depicted herein areMore information
CACHÉ: FLEXIBLE, HIGH-PERFORMANCE PERSISTENCE FOR JAVA APPLICATIONS A technical white paper by: InterSystems Corporation Introduction Java is indisputably one of the workhorse technologies for applicationMore information
Java (12 Weeks) Introduction to Java Programming Language
Java (12 Weeks) Topic Lecture No. Introduction to Java Programming Language 1 An Introduction to Java o Java as a Programming Platform, The Java "White Paper" Buzzwords, Java and the Internet, A ShortMore information
Rational Software White Paper
Mapping Object to Data Models with the UML Rational Software White Paper Table of Contents SOFTWARE DEVELOPMENT FOR DATABASE APPLICATION...1 THE APPLICATION MODEL...1 THE DATA MODEL...1 THE UML PROFILEMore information
Mobile web apps: The best option for business? A whitepaper from mrc
Mobile web apps: The best option for business? A whitepaper from mrc Introduction Mobile apps have finally reached the point where businesses can no longer afford to ignore them. Recent surveys and studiesMore information


text:
|To find the lowest Adoxa prices, click below on the strength of interest.
|Choose Strength for: Adoxa - Brand Version
The lowest prices for Adoxa from online pharmacies and prescription discount cards! Before you buy Adoxa, compare the best prices on Adoxa from licensed, top-rated pharmacies in the U.S., Canada, and internationally. Find the lowest cost Adoxa from the best pharmacy.

subset: commoncrawl


text:
Training Services
Mustain Kennels offers puppy training as well as Natural Ability preparedness:
- Hunting Preparedness is basically "starter dog" training. This includes tracking, flushing, pointing, and retrieving, along with basic commands to develop your hunting partner's natural abilities. We recommend this training for 6-10 month old pups to hone their hunting skills and prepare them for the field and water. Price depends on amount of time to train, usually 6-8 weeks. Cost is $25/day plus the cost of birds.
- We offer a special Puppy Training package to our puppy buyers of an additional 4 weeks of training and socialization (from 8-12 weeks) for an additional $100.00 per week. This includes potty training, basic commands, leash training, riding in cars, crate training plus a very basic introduction to Hunting Preparedness - into to birds, pointing, tracking. This allows the pups additional time with mom in addition to our other adult dogs and puppies for optimal socialization.
- Natural Ability Test Preparedness – similar to Hunting Preparedness, this training will prepare your dog to take the NAVHDA Natural Ability Test as well as field and water training, basic commands, etc. Price is $1,000 and includes registration for the NA test as well as transportation to the test site and John acting as handler during the test.
For more information on the above packages or to discuss other training needs, please call John at 816-868-7629 – we'll be happy to discuss your training requirements and develop a program that fits your needs.


text:
Element Power
From Open Energy Information
Element Power is a company based in Portland, Oregon. Element Power develops, acquires, builds, and operates utility-scale solar and wind power projects. Through partnerships with landowners, other developers, utilities, government entities and equipment manufacturers, Element Power develops projects that are both profitable and sustainable.
Element Power has projects in North America, South America, and Europe. Just recently, Element Power placed an order with Vestas a large wind turbine manufacturer for a wind project in Luna County, New Mexico, a project that will develop 99 MW of utility-scale wind power.


text:
To ensure you have the best opportunity to recover your orders,
we've launched a brand new Facebook Messenger integration.
This allows you to create mixed recovery sequences that might look like the following,
The power this unlocks over your competition is huge. While the inbox becomes more and more crowded, you'll enjoy cart recovery in a new, untapped medium.
Smart Cart Recovery gives you the power to follow up with your customers based on their referral source in an easy to use drag and drop interface.
In social media, tailoring your content to the particular platform is common place. We share cool images to Instagram, text and image-based content to Facebook and videos to YouTube. Why not carry that conversation through to your abandoned cart recovery attempts?
This means that a generic message like,
Hey, we saved your order, come back to claim it".
Can turn into,
"Hey, we're offering a special deal for our Instagram audience! Yep, if you complete your order now, you'll enjoy a 100-day money back guarantee!! Crazy, right? Just complete your order below to claim your money back guarantee!"
This type of interaction will increase your conversion rates to your store as your audience become more connected to your brand and product.
We offer a 14 day free trial on this product (which is usually long enough to save at least one sale). Why not give it a try?
If after the trial period you feel the app hasn't made an impact in your store, simply remove it via the "Apps" section of your store.
Orbit Campaign - Create On-Site Upsells, Email Marketing Sequences & SMS Sequences To Increase Revenue
Sky Watcher - Show Real Time Viewers On Your Products


text: Many thanks to our wonderful audience members who joined us this past weekend for A Festival of Dance! Thank you to our brilliant NWDT dancers, Artistic Director June Taylor-Dixon, choreographers, guest dancers, production crew, parent members and volunteers who made this production such an incredible experience! Well done everyone – we are so proud of you all. And thank you to our donors and patrons for letting us share the joy of dance with you and for making NWDT possible. We look forward to seeing you all again in December for A Nutcracker Tea 2017!


text:
Latest articlesTips on applying for a scholarship
In today's world employers receive about 200-500 applications for each scholarship opening. They just received a bunch of dates and numbers and little personal information of candidates. Therefore is it very difficult to judge a potential candidate without having interview and personal discussion.
Conclusions of the 9th meeting of Steering Platform on Research for Western Balkan Countries
The Steering Platform heard the introductory statements from Montenegro, the Belgian Presidency and the European Commission, highlighting the recent policy actions taken at EU and regional level...
Parent Category: Health
» Acne
» Aging
» Beauty
» Diet
» Exercise
» Fitness
» Hair
» Medicine
» Nursing
» Pharmacy
» Services
Featured Links
|How to Get HGH Injections
When it comes down to pain, you want to be able that you have as little as possible for your elder years so you can enjoy them. Before you found the HGH Therapy In Houston TX, you were probably in a load of pain from your joints and muscles, but you, just like so many before you, decided that there big memories from big old Texas were worth keeping more. Prescription HGH Injections can be used to save your memories and truly boost your immune system in a way that you need as you get older.
|Get HGH in Texas
Having the look you want is integral to feeling like you are worth the best you can find, and when it comes to self esteem, nothing else proceeds the thoughts of look in our heads, even though others may be more strong. With HGH Injections, age no longer is a factor to keep the look you want long after it was supposed to leave you, and when you turn seventy and still feel forty, you, too, can look back at the HGH Facts And Benefits you first saw and list off all that had helped you.
Links Sort by: Hits | Alphabetical
|Best Wrinkle Cream
An educational site about the best wrinkle creams
An educational site about the best wrinkle creams


text:
These are my latest aceo's ;o) The zentangle one is called, "Hearts Of Fire", "After the first kiss, they knew". and the baby crow one is called, "Snowball Fun", "Play Time". Enjoy ;oD
Saturday, October 2, 2010
Two New Aceo's ;o)
Posted by Magic Love Crow at 1:36 PM
Labels: acrylic, baby crows and crows, hearts of fire, new original crow zentangle aceo, snowball, two new aceo's
10 comments:
Looking good Stacy!ReplyDelete
Thanks My Friend ;o)ReplyDelete
Love that snowball fight! Very cute ;)ReplyDelete
Hearts of Fire is lovely, Stacy.
Hearts of Fire is just gorgeous, and Snowball Fun is really cute =)ReplyDelete
Great job!
Thanks Debbie ;o)))ReplyDelete
Hugs Lee ;o) Thanks so much!!!ReplyDelete
Thanks Kathyrn ;o) Much Appreciated!ReplyDelete
They look great :)ReplyDelete
Thank you for taking the time to comment! I'm very grateful! Your words are very special to me! Big Hugs!
Subscribe to: Post Comments (Atom)


text:
We were invited on vacation to celebrate my mother in law's and my hubby's niece birthday in the greek island crete. It was a wonderful week of sunshine, great food, drinks, beach, pool and entertainments. We had lots of fun and family bonding time. We rarely get a full week with David, so it was a great for Julia to be with her dad longer as she is growing and developing new skills and senses everyday.
As lucky as I usually am... my birthday happened to be on the 5th of June during our stay there. I got a lovely chocolate cake from the Hotel Panorama Hotel . My parents in law bought me a "massage experience" in Ageo Spa which was outdoors with sea view and sea breeze.
The mediterranean fish and other oriental dishes were also a gift from heaven to me. I soooo missed lots of these things while living in a completely different environment from where I grew up. The island gave me the feeling of being home again.
I gave myself treats by visiting a nail bar spa and got myself a good beautiful feminine long nails which I don't usually do hehe... and a great feet treat and of course pedicure.
More photos here


text:
You are simply the best! Fast shipping, thoughtful email and a handwritten note included in with your beautiful fabric made shopping with you a most enjoyable experience! You know how to keep me coming back for more!
Many thanks,
Paula H. - Charlotte, North Carolina
Our goal is for QuiltHome.com to become one of your valued sources of quality quilting supplies, information, and inspiration. We welcome your comments, suggestions, observations, and bug reports.
Please leave your Comments HERE.
For over a decade, Brandon Mably has been the Studio Manager of Kaffe Fassett Studio in London England, and has worked closely with Kaffe in the design, creation, and execution of knitwear, tapestry, patchwork, mosaic, and mixed media artwork. While working side by side with Kaffe, Brandon has honed his unique style of bold design and vibrant colour.
from Brandon's Site
0 items


text:
Lollapalooza by Moondog
It's almost that time again – starting this Friday, the masses will once again converge upon Grant Park, Chicago to see this year's arguably best concert-festival line-up. I'll be there, along with a few other KWUR folks, and we're going to be reporting live as only KWUR DJs can. So, keep your eye on the blog in the next few days for pictures, updates on the shenanigans, and whatever else I feel like posting after hanging out with crusty hippies at the Blues Traveler show.


text:
I have been working on an algae, cya problem for 2 weeks. I had a party Labor and all the "experts" who think they know everything said add muratic acid to the skimmer. Another said add soda ash. I know all theses things are relevant to a specific problem and will cause a different problem if it is not there now.
We have added bleach and bleach and bleach. Ph is about 7.2, ta is 110, cya is 60, chlorine right now is pegged on the kit I have. I have ordered a more specific kit for higher chlorine levels but it's not here yet.
What is muratic acid actually used for? My pool surface already needs resurfacing so will it hurt it?


text:
Open Thread: Everything You're Reading, Watching, Listening To and Looking At
This is your place to talk about the TV, movies, music, books and art that are thoroughly entertaining you.
Read more from Hannah on xoVain.com!
Whenever a new year begins, one of my goals is always to read more. And I'm doing pretty well -- I read nearly every night before bed, or in the evenings while sitting in the bathtub, and I feel much better for it because, hey, reading is the best.
Since this year has started, I haven't read any fiction. Instead I seem to be following a pattern of reading true-life tales of life in the 20th-century, and I don't have any plans to stop.
It started off with reading "Please Kill Me: The Uncensored Oral History Of Punk," a book that had been in my collection for a pretty long time but I'd never gotten around to reading until January of this year. When I started the book, I wasn't expecting that it was going to be an oral history (even though, NEWFLASH Dumb Hannah, it says so right in the title). No, I expected some sort of rigid, chronological detailing of the events that lead to the birth of punk music which, looking back, would probably be pretty boring and ill-fitting of the subject matter.
Instead, it was (thankfully) conversational-style stories culled from years of interviews, hours-upon-hours of tape edited down to the most lurid, inspiring and hilarious tales from those who lived and breathed it all, and naturally I devoured the book with an excited and sometimes disgusted fervour. If there's one specific thing I learned from it all, it's not to shoot up with puke-y toilet water.
Once I finished PKM, I went back in time again and picked up "Edie: An American Biography" (which has a different sub-title on Amazon but it's the same book, my copy is just old). A big chunk of content in the middle of the book overlapped with some things I had previously read in Please Kill Me, and a lot of the same cuckoo people showed up, but there was still a different perspective, and a lot more history to be told, particularly about the fascinating world of early 20th century, old-money New Englanders.
I was held rapt reading about the Sedgwick family's rocky ups and downs and various dark secrets hidden throughout their lives, long before Edie was even born. The Sedgwicks' lives were deeply plagued with tragedy, and I have no interest in recreating Edie's world, but I found the stories about her incredibly compelling -- her charm, even shining through at her worst, came through the page when her friends (and some enemies) recalled her life. She was an electric figure who could draw anyone into her vortex, and even when I read about her most deplorable actions, I pitied her and needed to read more, usually poring over the book's text and photos through the night and into the early hours of morning.
I finished "Edie" quickly and, finding a dearth of further oral histories in my book collection, am now reading Joan Didion's "The White Album." I guess you could say it's a one-person oral history, Joan's collected essays on the decade of the '60s giving you an insightful glimpse into the intense years through the eyes of the keenest observer. I'm loving the book so far (I don't think Joan can really do any wrong) but now I'm wondering what to pick up when I finish.
I guess that's where you guys come in. Recommend me your favourite oral histories, why don't you? And if you've read any of the books I mentioned above, let's chat about them. Or just tell me what you're reading regardless -- graphic novel, memoir, the latest issue of Cat Fancy. It's all good.


text:
Waffles got her very first BarkBox!
Bark & Co. Andi's Famous Dumplings
Nootie No Grainers NYC Jerky Chews-Roasted Duck Recipe
Grain and gluten free
Bark & Co Best Treats Ever! Duck and Turkey Strips
Bark & Co. Lady Liberty Ball
Butcher's Block Bones Krunchie Tube
She absolutely loved everything! She carried around all 3 of the dumplings at once, showing them off to everyone!
Right now, you can get 50% off your first box at www.barkbox.com or if you use my referral link, your first box is FREE! https://www.barkbox.com/r/JVCXAYDXP3. Their regular price is $25/month with a 6 month subscription. SO worth it!


text:
New Arrivals
2018 Nissan Frontier PRO-4X Truck Crew C…
- $35,060
- Truck Crew Cab
- Gray Exterior
- 4.0L V-6 cyl Engine
Trust our factory trained technicians to deliver expert service and advice on how to care for your vehicle.
LESS THAN 80k MILES
Pass a 167 POINTS inspection
7 year/100k miles
Not only will you find New Nissan models at our dealership, serving the greater Oakland, Berkeley, Richmond and San Francisco areas. You'll also find a friendly and accommodating staff eager to assist you.
That's true no matter what you're looking for - be it a test drive in a new Nissan Altima, Sentra, Pathfinder, Rogue, Maxima or used car, auto financing options, car service appointments, or help figuring out what auto part you might need.
The first thing you'll notice when you step into the Autocom Nissan of Oakland showroom is an amazing selection of new Nissan models to choose from, including the Nissan Altima, Sentra, Pathfinder, Rogue and Maxima. We carry a wide range of models that make cruising Oakland, Berkeley, Richmond and San Francisco a more enjoyable experience, and a test drive is never more than an inquiry away.
Though buying a new car is an undertaking, we understand you've got more going on in your life. Perhaps you've been planning for a big vacation? Whatever it is, one way you can save big is through our collection of used cars. We have a wide range of options that are sure to satisfy you as well as your checking account.
Autocom Nissan of Oakland Also Offers Auto Financing, Nissan Leases, Car Service, and Nissan Parts
Bring those dreams of a Nissan Altima, Sentra, Pathfinder, Rogue or Maxima in your garage to a reality with the help of our flexible auto financing opportunities. At our dealership in Oakland, our team of experts is ready to dish all you need to know about our available car loan and lease options. Bad Credit or No Credit see if we can help. Stop by today to find the car that's right for you for a price that's right too.
The fun of something new doesn't have to end when you drive your Nissan Altima, Sentra, Pathfinder, Rogue or Maxima off our dealership's lot. Autocom Nissan of Oakland has many ways to keep your car fresh and your driving experience exceptional.
We offer authentic Nissan parts to enhance the performance, style, or convenience of your vehicle.
Furthermore, our dealership in Oakland is dedicated to keeping your Nissan model running just as well as it did on day one. Our handy onsite auto service and repair department is here for you, whether it's routine upkeep or handling the unexpected.
What else does Autocom Nissan of Oakland have to offer? Aside from expert knowledge in everything automotive, we simply love serving you. So come see us today, conveniently located at 2735 Broadway, Oakland, California 94612. Be sure to bring your questions, and be ready for answers.


text:
This item is temporarily out of stock. However, we can notify you as soon as this product becomes available.
Thank you
We have received your request and you will be notified as soon as this product becomes available.
In order to keep our prices as low as possible, all CreateForLess order subtotals must be at least $10. This helps us save on labor costs when packing your order so we can extend the savings to you!
Description: Fiskars wide selection of Punches cut paper in intricate patterns and shapes, create a gorgeous border, round a corner in style, or even add embossing Teresa Collins XOXO- Bold graphic of "hugs and kisses" letters all linked together. Sophisticated designer style in a punch that requires less force and with built-in technology that helps prevent paper jams. About 1.9 in. tall.
See more Fiskars Punch.
Review this product and Enter
to Win a $100 shopping spree!


text:
This post contains mild spoilers for DAI: Jaws of Hakkon.
Warning: contains spoilers for Dragon Age: Inquisition and Dragon Age: Origins.
Hi. I'm Mahamari, and I like to draw and build stuff. :D
This is where I write about my doodles, gaming escapades, and creative projects.
Right now, Twitter is the easiest way to reach me. I like making new friends, so feel free to find me there!
Follow my personal tweets at @mourneblade and art-related/official tweets at @mahamari.
Tweets by @mourneblade
Tweets by @mahamari