Level: Any, Version: FM 8 or later

Life After Anchor/Buoy

t-s-eliot-exploration2

INTRODUCTION

Earlier this month I was contacted by a DevCon presenter asking permission to include some slides from my eleven-year old anchor/buoy materials as part of his presentation. I said I’d be honored, but then added, “You might mention that I haven’t used A/B on a new project in about eight years.” He asked what system I was using instead, and a number of other colleagues have wondered as well, which brings us to the topic of today’s article.

Note: Anchor/Buoy has recently gained a new lease on life thanks to the selector-connector technique. In my opinion, A/B’s drawbacks outweigh its benefits, selector-connector notwithstanding.

Various developers have told me over the years that their main reason for adopting A/B was that it gave them a clearly-stated specific set of guidelines to follow with regards to graph management; with this in mind I have enumerated a set of post-A/B guidelines below, which I believe to be clear and specific.

To avoid any misunderstanding, I am in no way suggesting that the FM community should adopt my way of doing things — or that those who practice A/B are doing anything wrong. These are my thoughts on the subject, and as the saying goes, your mileage may vary.

THE BACKDROP

First I’d like to ask you to mentally rewind to March 2004, and recall the disruptive paradigm shift that occurred with the release of FileMaker 7. Suddenly developers were confronted with a myriad of contextual issues that had hitherto either a) not existed, or b) been handled implicitly by FileMaker behind the scenes. A common lament at that time was “We’re all newbies again” (another was “I’ll stop using 6 when they pry it from my cold dead fingers”).

Clearly the FM 7 relational model was significantly more powerful than its predecessors, but many experienced developers felt a sense of unease, bewilderment and/or deep philosophical and emotional angst when confronted with the Relationships Graph.

Below is an early incarnation of my first FM 7 graph. Like many, my inclination was to build something bearing a strong resemblance to an entity-relationship diagram (ERD), and I worked out some of the nuances of the data model directly on the graph.

kf_music_db_graph_v1

However, as I noted at the time, while the Relationships Graph plays a vital role in all three “layers” of a database solution…

2016-07-25_093154

…an ERD only describes this layer:

2016-07-25_093510

A/B TO THE RESCUE

So, emulating an ERD on the graph appeared to be a dead end, and I disavowed it…

2016-07-25_111558

…and was quite happy to do so, having in the meantime discovered and embraced anchor/buoy. For the next few years I used A/B on all my projects, and evangelized it online, in print and in person.

But there was always a bit of cognitive dissonance. For one thing, at various times respected FileMaker luminaries such as Jimmy Jones, Ray Cologon, Ugo Di Luca, Mikhail Edoshin, and at least one FileMaker engineer, declared that A/B was a flawed methodology.

For another, it didn’t take a genius to see that this…

2016-07-24_12-14-30

…was more intuitive and less convoluted than this:

2016-07-24_12-53-31

(In fairness, I have never seen an A/B solution with a level of redundancy that was quite this extreme, but it does demonstrate what would be necessary to fully replicate the functionality of the non-A/B version.)

Also, as time passed the post-6 paradigm began to make more sense, and contorting FM7+ to emulate FM6 no longer felt as necessary as it previously had.

And, finally, evidence began to accumulate that additional TOs on the graph were not “free”, and that the profusion of joins could negatively impact solution performance.

To cut to the chase, while I continue to work on various teams where A/B is the in-house standard (and some where it is not), I made a decision in 2008 to stop using A/B on my own projects.

A POST-A/B EXPERIMENT

So, when one stops using A/B, what does one replace it with?

I have occasionally experimented with natural language TO naming… but only on small systems that are not expected to evolve into large systems. Shown here is an entire graph, not a subset of a larger one.

rg-natural-naming

One thing I like about this approach is that the TO names help to document the solution… but this approach does not scale well, and I would not consider using it except on the simplest projects.

POST-A/B AIMS AND METHODOLOGY

Currently my aim is to strike a balance between having my graph resemble an ERD on the one hand, and retaining certain things I like about A/B on the other… e.g., a rock solid, easy-to-use naming convention. If I had to sum up my post-A/B methodology in a single sentence, it would be: “Connect everything, except when it makes more sense not to.”

Shown below is a portion of a graph from a complex project, and it represents approximately 25% of the total graph. Note that there is one large TOG (table occurrence group) followed by four smaller TOGs. Since this is a subset of the total graph, you will see a number of buoys without seeing their corresponding anchors — yes, I know, referring to TOs on a non-A/B graph as “anchors” and “buoys” may seem strange. For a while I tried to force myself to use other terms, but I still think of them as anchors and buoys, and it would be disingenuous to pretend otherwise.

2016-07-25_15-40-41

GUIDELINES

These are general guidelines, as opposed to hard and fast rules, and one should feel free to make exceptions as necessary (e.g., see the note following #14 below).

  1. Each table has a single authoritative representation on the graph, i.e., an anchor
    • Layouts are always attached to anchors
    • Calculations, auto-enter calcs, etc. always “start” from anchors
  2. All other TOs are referred to as buoys
  3. Table names are always a single word and never contain underscores
  4. Anchor name = table name
  5. Buoy names reflect the path from the anchor (e.g., contact_scan_SCANMISC)
  6. Underlying table name in all UPPERCASE on both anchors and buoys
  7. Color coding reflects the underlying table
    • Except grey is used for all minor tables
  8. On the graph, anchor TOs are expanded, buoys are not
  9. Underscore characters…
    • Only appear in buoy names
    • Are used as a table separator exclusively
    • Multiple consecutive underscores are not used; they will only cause confusion, and #3 and #10 render them unnecessary
  10. Where desirable, a period can be used to append a descriptive label
    • But only on buoys; never on an anchor
  11. Buoys can stretch leftward or rightward from anchors; direction doesn’t matter
  12. TO lists reflect the hierarchy of buoys below their parent anchor, e.g.,

2016-07-19_15-37-57

  1. Anchors can be linked to other anchors via primary and foreign keys
    • …in effect forming a pseudo-ERD
  2. However, if you don’t see an obvious spot for an anchor in one of your pseudo-ERDs, instead place it in a separate TOG
    • For example, SCAN makes many appearances on the RG, but there isn’t one obvious place the anchor belongs, so it gets its own TOG

Note: if you take a close look at the graph example, you may wonder why SYSTEM is connected to ITINERARY since it appears to deserve its own TOG as per the preceding.

Explanation: the SYSTEM table provides the foundation for a dashboard used by administrators. The dashboard layout contains a number of portals, and originally SYSTEM was given its own TOG. However, after I had built a considerable amount of functionality into the dashboard interface, the client requested access to much of that same functionality from within a tab panel on an ITINERARY layout. Making an exception (to #14 above) and connecting SYSTEM directly to ITINERARY neatly solved the problem, saving considerable time, money, aggravation and graph bloat.

CLOSING THOUGHTS

Two of my favorite things about FileMaker are its depth and its flexibility. There is rarely a single best way to do things, and what works for me, of course, may not work for you. The above methodology provides a system that is as “automatic” as A/B, but that I find to be more cohesive, clear-cut and easier to work with. Bottom line: moving away from A/B has been like a breath of fresh air for me, and I don’t regret the decision at all.

20 thoughts on “Life After Anchor/Buoy”

  1. Kevin,
    Thank you once again for a fresh take that isn’t bound by previous convention and your perpetual pursuit of practical automation and efficiency in real-world solutions! And thanks for sharing.

  2. Nicely thought out. Thank you, Kevin!

    You’ve described some things I’ve been thinking about (and partially implemented), but haven’t codified. It seems like you’re keeping the strengths of AB and removing much of the overhead.

    Another thing I’m always concerned about is file opening performance, especially over the WAN. So to reduce that load, maybe #15 should include a separate TOG for any opening screens / dashboards the UI requires.

  3. Damn that was a relief to read! Always faintly queasy when lifting the hood on my RG where a B grade maritime movie is underway between a giant spider and various bits of nautical equipment. I too go for uppercase when naming underlying tables but prefer “|” as dividers. Only place TOs from right to left for some reason. Nice to know I’m in good company!

  4. As always, Kevin, excellent work. I do not use A/B on solutions that I develop by myself (I never have), but I always use it (still do) when developing large solutions with a team. Two comments:
    1. The problem I have with the omni-directional graph that has multiple anchors is that it makes the buoy naming convention difficult, plus it makes the UI for field selection very challenging for calculations, layout objects, sorts, etc. (both because of the naming convention not being unambiguous and because of the sheer number of related TO’s).
    2. It is my understanding that the only performance penalty of having more TO’s and relationships is when the file is initially opened (and this is only a substantive issue over a WAN, which doesn’t apply to all solutions). If there are other performance implications, I would love to know this.

    1. Hi Danny,

      Thanks for taking the time to write that up.

      Re: #1, it has not been my experience that buoy naming is more difficult… whether they stretch rightward or leftward makes no difference in terms of naming (of course you still name them from left-to-right). In other words, the system is surprisingly A/B-like and buoys still function pretty much the same way they always did, except there are a lot less of them. I will concede that you don’t get that tiny “safe” set of “related” TO’s to choose from when, for example, defining a calculation, but a ) if you use selector/connector you don’t get that either, and b ) in 2005 I thought it would be a problem, but subsequent years have proven that not to be the case.

      E.g., if I have a specialized buoy hanging off of CONTACTS (let’s call it “contacts_CONTACTS.xyz”) and now I need to access that info from a TO based on INVOICES, I point to contacts_CONTACTS.xyz, as opposed to defining a new buoy (“invoices_contacts_CONTACTS.xyz”).

      Making the transition has been surprisingly painless, with zero confusion. Really it’s just a question of getting comfortable with a slightly different paradigm.

      Re: #2, when I asked Chris Crim about this, admittedly, more than a few years ago, his response was “We keep track of everything, and everything has a cost… but that doesn’t mean you shouldn’t use A/B”. In addition to the opening slowness you mention, I recall a “what’s faster” session at POE a few years back demonstrating that a simple operation took twice as long on a simple A/B graph (2 TOGs, 4 TOs) vs. a “normal” graph (1 TOG, 2 TOs).

      FWIW,
      Kevin

      1. Happy to bounce this around with you, Kevin. :-)
        Further to #1: I think that we may be talking about a matter of scale. Also, again, it’s not about whether it’s clear to the original developer, but whether another team member can make sense of the name immediately. I find that when there are more instances of TO’s in the same TOG that are based on the same table, that the names are necessarily less simple.
        Regarding #2: the concept that “everything has a cost” is relative. FWIW, my assertion in my previous comment regarding performance was reaffirmed by a conversation that I had with Clay Maeckel at this past DevCon just a couple of weeks ago. Based on that, it makes no sense to me that a simple operation on a simple A/B graph would take twice as long as on a normal graph (nor is it my experience). At the time of execution, FileMaker doesn’t reference the graph at all, but rather an internal table of joins that was created at launch (from the graph).

        1. Hi Danny,

          Perhaps others who recall the experiment I mentioned will chime in re: #2.

          With regards to #1, do you see names on my RG that are more complex than would be the case in a pure A/B system?

          Kevin

        2. Did Clay (or anyone) comment on whether a graph with many joins takes longer to save during schema updates? I’ve seen some A/B monstrosities (not built by me) take a very long time to close when a developer clicks okay after making a simple schema change.

          1. I can confirm that large RGs take several seconds to save; one project I worked on had easily 250 TOs in each of several files and saving changes would take ~20 seconds.

  5. This is a great, clear explanation of something I think a lot of us arrived at independently. I always called something like this a “hybrid” structure, because it still includes what’s best about A/B but reincorporates what was most sensible about the old “octopus” approach.

    My problem with A/B is that semantically, it doesn’t always make sense. It gives you a technical structure that works around the technical specifics of FileMaker’s way of doing things, rather than representing the semantic meaning of the tables and their relationships.

    If you have a table called “Invoices” and a child table called “InvLineItems”, then anywhere you can reference “Invoices”, “InvLineItems” should automatically make sense. Any layout structure depending on Invoices should be able to be copied and pasted to any layout on which “Invoices” makes sense semantically as a related entity to what the layout is based on (Customers/Vendors/etc.) without included objects referencing “InvLineItems” breaking and having to be rereferenced. A/B doesn’t do that. “Hybrid” (or whatever you want to call it) does.

    This is especially useful for any later developers who might wind up working on the file, as the semantic understanding of the system yields the working relationship between the main TOs.

    I have some differences on the details, but not worth quibbling over here.

    1. Hi Michael,

      Well stated. I have little doubt that moving away from A/B has allowed me to have an intuitive, and even “organic”, sense of my solutions as a whole that I did not previously have. I actually enjoy development more.

      Thanks,
      Kevin

  6. I seem to have found a new fresh air for anchor/buoy which may make you consider using it again. My team has discovered that there connecting all TOs into a single TOG can lead to a significant performance penalty. We actually recently optimized our core system by converting it from the spider model to anchor/buoy. It was a lot of effort but it was worth it.
    I will be talking about it in my DevCon session this Tuesday at 2:15pm, but feel free to also come to the 24U Software booth discuss it in person.

    1. Hi Honza,

      As I said in the article: “Connect everything, except when it makes more sense not to.”

      I am intrigued by your findings. When you write this up please post a link here.

      Regards,
      Kevin

  7. Found this article when looking for something else. As of today (2022), thanks to the initial urging of the great Mr. Koudelka, smaller TOGs are commonly regarded as the performance leader. As a devout “Frank-o-phile,” I am eager to find a more recent article on the subject from Kevin.

      1. The only correlation with GetFieldName is that using the function is one of the (several) cases when FileMaker decides it needs to examine the dependencies and possibly also refresh the “master map of table occurrences”, which is the operation most (exponentially) affected by the size of each TOG.

Leave a Reply to Kevin FrankCancel reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.