punkish has asked for the wisdom of the Perl Monks concerning the following question:

The above can be modeled as

@arr = ( {person => 'PersonA', place => 'PlaceA',} {person => 'PersonB', place => 'PlaceB',} );

which can be stored in

CREATE TABLE tbl ( person, org )

Moving on, PersonC works for PersonA. Yes, I could simply do a push @arr, {person => 'PersonC', place => 'PlaceA'}, but I really want to do

@arr = ( { person => 'PersonA', place => 'PlaceA', has_assistant => 'PersonC', } { person => 'PersonB', place => 'PlaceB', has_assistant => 'PersonC', } { person => 'PersonC', place => 'PlaceA', works_for => 'PersonA', } );

or, I can de-sparse it (but, do I have to?) as

@arr = ( { person => 'PersonA', place => 'PlaceA', works_for => '', has_assistant => 'PersonC', } { person => 'PersonB', place => 'PlaceB', works_for => '', has_assistant => 'PersonC', } { person => 'PersonC', place => 'PlaceA', works_for => 'PersonA', has_assistant => '', } );

which can be stored in

CREATE TABLE tbl ( person, org, works_for, has_assistant )

The complexity is likely to grow. We might want a 'works_with' relationship (sibling rather than sub-ordinate). There might be other predicates we might want to include later.

Ok, what are the better ways to model something like this? Linked lists? How? This screams of linked lists (implemented in hashes, no?), or RDF Triples. And, I want to store this nonsense, and I want to extract it from the store and display it as a network digraph, probably through Java, or better yet, via Processing http://www.processing.org in Java, or even Flash. Since there are several attributes about each node, a standard rdbms (SQLite for prototyping, then PostGres for production) would be the preferred store, unless there is a better format. All ideas welcome as this is still in the design phase.

--

when small people start casting long shadows, it is time to go to bed

Replies are listed 'Best First'.
Re: modeling relationships
by fmerges (Chaplain) on Feb 07, 2007 at 15:39 UTC

    Hi,

    You should use more tables, and relate them using the ids.Don't forget the many-to-many relations...

    Also something useful is to use an Object Relational Mapper, like DBIx::Class

    Update: You can also use GraphViz for displaying the data

    Regards,

    fmerges at irc.freenode.net
Re: modeling relationships
by fenLisesi (Priest) on Feb 07, 2007 at 15:50 UTC
Re: modeling relationships
by klekker (Pilgrim) on Feb 07, 2007 at 16:05 UTC
Re: modeling relationships
by talexb (Chancellor) on Feb 07, 2007 at 18:18 UTC

    I sense some confusion -- you describe Perl data structures, yet you then show how they could also be represented in a database.

    Assuming you're going to be dealing with a database, you could have a Person with the attributes name and place_of_work, if we make the assumption that a person has just a single place of work (that is, it's a one-to-one relationship).

    There are a number of ways to set up the relationship where a Person has an assistant (who is also, no doubt, a Person), depending on how your universe is structured. If one Person could have one to many assistants, but each assistant would work for just one person, then you could point each assistant to a Person (usually done with an ID). If one Person could have just one assistant, then you could get away with a single pointer, from the Person to the assistant and/or vice versa. If you go the complicated route, and multiple Persons would share multiple assistants, then you'd have to go to a releationship table where Persons would be linked to the appropriate assistants.

    I would stay away from thinking about implementation details (linked lists?) until you have a firm grasp of the data structure. The best possible way to implement this is definitely in a database, whether you use something light like SQLite, or go heavier with MySQL or PostgreSQL.

    The advantage with using a database is that a) the data's stored somewhere safe, b) you can use SQL to pull out exactly what you want, and c) you can try various different architectures without tearing your hair out trying to debug an array of hashes containing more arrays ... you get the idea.

    Alex / talexb / Toronto

    "Groklaw is the open-source mentality applied to legal research" ~ Linus Torvalds

      I describe Perl data structures because I am able to wrap hashes around my entities. I try to represent them in a db because that is the first thing that comes to mind for persistent storage and rapid retrieval.

      In my OP, I have only described People. I could have entities that are Organizations, and either of these entities could have a multitude of properties. One of the key properties would be the relationship of these entitites to each other. So, a person (with its bundle of properties) could "works_at" an organization that "works_with" another organization that "employs" another person who is "married_to" another person who "works_at" the first organization, ad infinitum. The more I stare at this, the more it says, we are "RDF Triples." I want to semantically describe the agents and agencies in a community (of such agents and agencies), and I want to do so in a machine recognizable way.

      The rdbms is great for structured data, but fails miserably for open-ended, free-floating data structures such as this (I often wonder why an rdbms data store wasn't chosen for the ical reference).

      I am just starting to walk on this road, by I need the wisdom of monks to guide me as I start.

      --

      when small people start casting long shadows, it is time to go to bed
Re: modeling relationships
by b10m (Vicar) on Feb 07, 2007 at 16:21 UTC

    DBIx::Class and Class::DBI should help you out here -as mentioned-, but maybe you may want to look into modules such as Tree::Authz to set up groups and roles.

    --
    b10m

    All code is usually tested, but rarely trusted.
      Thanks. Tree::Authz seems very interesting. I feel that an rdbms is perhaps not the best way to model such a network structure. Something like Tree::Authz is probably better (am I looking for an XML-ish solution here?). But, then it probably should be stored in an rdbms for ease of management and speed of retrieval.
      --

      when small people start casting long shadows, it is time to go to bed
Re: modeling relationships
by NetWallah (Canon) on Feb 07, 2007 at 18:13 UTC
    It would help in both Programming, and database schema, if you abstract the problem, and think in terms of objects, relationships, properties and KEY fields.

    In your case, the primary object is "Person" with a person-ID as a Key field.

    The person(object) has a Property - "place".

    The person has what appears at first sight, to be 2 "relationships" - whach can be named "assistant" (Can there be more than one ?), and "Boss/Works-for" - again - can there be more than one ?

    If you think about it, these relationships define the same thing, and you can avoid a multitude of data integrety and programming erros by using a single relationship for this - I would suggest a "boss" relationship, which is usually a one-to-one. This allows a "boss" to have multiple assistants, but an assistant to have 0 or one boss (The person with zero bosses it the head honcho).

    So, your table becomes:

    CREATE TABLE Persontbl( person, org,location, boss-link )
    And in perl, you can store this as a simple hash with "person" as the key. The "boss-link" will be a ref to another "person", or undef.

         "A closed mouth gathers no feet." --Unknown

Re: modeling relationships
by dragonchild (Archbishop) on Feb 09, 2007 at 01:40 UTC
    A data structure's form exists for one reason - to retrieve data. Don't look at what you want to store - look at what questions you want to ask. If you need to ask a lot of traversal questions, then store it as a tree (or, more generally, a graph). If you need to ask a lot of specific "What is your name?"-type questions, store it as an array of objects.

    Furthermore, the way you store it on disk IS NOT the way you should handle it in RAM. How it is persisted in a permanent datastore and how you instantiate the data in your program are completely unrelated, save for the mapping between them. Storage on disk is marked by a paranoid avoidance of repetition. Storage in RAM, given that the disk is the ultimate arbiter, is more forgiving of repetition.

    In other words, it's ok to load a bunch of data from the database, manipulate it a whole bunch, then use it. Just because the database views stuff one way doesn't mean you have to.


    My criteria for good software:
    1. Does it work?
    2. Can someone else come in, make a change, and be reasonably certain no bugs were introduced?
Re: modeling relationships
by planetscape (Chancellor) on Feb 09, 2007 at 03:24 UTC

    Perhaps the book Joe Celko's Trees and Hierarchies in SQL for Smarties by Joe Celko would be of interest.

    From the back cover:

    In this book, Celko illustrates several major approaches to representing trees and hierarchies and related topics... These topics include hierarchical encoding schemes, graphs, IMS, binary trees, and more.

    HTH,

    planetscape
Re: modeling relationships
by pajout (Curate) on Feb 08, 2007 at 11:14 UTC
    I see following rdbms structures:

    person id name place id name works_at id person_id place_id works_for id master_person_id slave_person_id

    But it very depends on cardinality of described relations. Can somebody work in two places? Can somebody work for two persons?

    My experience is to examine such questions very precisely, according to software specifications. If the answers are clear, there is no big problem to design physical data model of the database. And the perl structures will appear more naturaly...