views:

70

answers:

3

First post, please be kind.

NOTE: I have reviewed entry #20856 (how to implement tagging) but feel this is different due to the fact that the tags method I'm considering is organization specific in my app. I’m hoping someone can confirm the direction I’m going or point out some other options.

(background) We are building a web application that gives different organizations visibility to their inventory in different locations. The database stores users, organizations, sites, and items and there are links from sites and items to organizations that allow us to determine which items / sites to show to which users (based on their organization).

It is common for two (or more) organizations to want to use the portal to check on the stock status of (for example) Widget A in the Los Angeles Warehouse. That part is fine. However, the different organizations also track unique information about Widget A. For example, Org 1 wants to track the color, volume, and primary vendor for each item. Org 2 wants to track Color, Stock Type, Inventory Cycle, Buyer Code for each item. I want to avoid a situation where I have to have a table loaded with all these possible fields and then figure out which organizations use which fields.

I’m considering using something along the lines of tags, but adding a tag category, and having the tag category be defined at the Org level. So, the basic table structure would be something like:

Table: OrgTagCategory
Fields: OrgId, TagCategoryId, CategoryTitle

Table: OrgTag
Fields: OrgId, TagCategoryId, TagId, TagTitle

Table: OrgItemTag
Fields: OrgId, ItemId, TagId

Then, when the user logged in the main dashboard the grid would include their appropriate item fields as columns in the grid. So, from above example, Org 1 would see Item#, Description (would be shown for all), color, volume, and primary vendor. Org 2 would be shown Item#, Description, Color, Stock Type, Inventory Cycle, Buyer Code.

Am I overthinking this or is there a simpler method of doing this that I’m missing? All thoughts / feedback sincerely appreciated.

A: 

That should be no problem, but you're storing the OrgId redundantly. Also it seems like there could be some overlap (probably a lot of overlap, realistically) between tags and orgs.

Here's how I'd do it:

  • Table: OrgTag

    Fields: OrgId, TagId

  • Table: Tag

    Fields: TagId, TagTitle

  • Table: ItemTag

    Fields: ItemId, TagId

This way each org is associated with the tags it's interested in, but you don't have redundant tags. A given tag that's used by multiple orgs just gets a bunch of rows in OrgTag, instead of multiple rows in Tag with the same TagTitle.

You'd only need a table OrgTagCategory if there were multiple tag categories per org. But you haven't described this extra association as a requirement.

Bill Karwin
Thanks for pointing out redundancy Bill. Nice clean solution.
Pat
A: 

My first quick thot on this would be that - if this is just limited to 'showing' particular fields to particular Orgs on Dashboard then it is better to handle it on the App side. If there's any other usage of 'tagging' then pls clarify.

Here's a simple approach - You can store a field [OrgDashboardFields] in the Org master table or the OrgItem table. This will be a comma (',') separated list of fields to be shown on the dashboard. At run-time fetch the [OrgDashboardFields] field and parse the comma separated list in the app and make the Dashboard Grid behave accordingly.

Or, if there's a dynamic-query framework then based on the [OrgDashboardFields] field you can create a dynamic SQL-query and get the desired result which is purely Org specific.

Hemant Tank
A: 

Based on your description I sketched a simplified model and combined it with the observation pattern. This should enable you to track various item properties and user preferences for viewing them. Admittedly, the Preference table may grow large, but data has to be stored somewhere anyway, and you may retrieve it using sql, which simplifies the business layer.

- Organization and person are types of users. User table has columns common to all users, while Organization and Person tables have columns specific to each one.
- A stock item (widget class) can be found at several sites (warehouses); a site stores many items.
- One item belongs to one user; a user can own many items.
- Measurement and trait are types of observations. Measurement is a numeric observation, like height. Trait is a descriptive observation, like color.
- An observation is of a specific type (height, weight, color), there can be many observations of the same type.
- One item (widget class) can have many observations, an observation relates to one item only.
- A user can prefer to display many observations; an observation may be preferred (to display) by many users.

alt text

UPDATE
We could simplify user's subscription to item details (observations) by tagging observation type, for example height, weight, width would be tagged with: all, dimensions, physical. Some other tags would be: accounting_interest, tracking_specific, etc. A user would then subscribe to tags only. Tags (could) form a hierarchy with ALL at the top.

- One observation type (height, weight, color) can have many tags, one tag belongs to many observation types.
- Each tag may have a parent tag forming a hierarchy.
- A user stores preferences for a set of tags that she usually monitors.

alt text

UPDATE 2
Now we can sort out who is who and who owns what. In this modification a user (now a person) can work for more than one organization (having several part-time jobs or contracts). An item belongs to a organization now. A logged-in user can see all items from all organization that she works for.

alt text

Damir Sudarevic
While this design is a bit more complex than I was looking for, I wish I could accept this as well because of the valuable reference to the observation pattern details, which are interesting to study. thx Damir.
Pat