Open a table in Yardi Voyager you've never touched before, and the column list looks like noise: hMy, hProp, sCode, iStatus, dtLeaseFrom, dSqFt, bActive, uCode. There's no data dictionary open in the other tab. But the noise isn't random — it's grammar. Once you know the rules, that column list tells you most of what you need before you've queried a single row.
The Hungarian-prefix system
Voyager's schema uses Hungarian notation: a short prefix encodes the kind of thing a column holds, before you ever see its name. Across the standard schema, the core prefixes are consistent enough to rely on:
h— handle, meaning a foreign key or primary key.hMyis the near-universal primary key name;hPropis a foreign key toPROPERTY.s— string.i— integer, almost always an enum/status discriminator rather than a freeform count.d— decimal, typically an amount or a measurement.dt— datetime.b— boolean, stored as a smallint or numeric rather than a true bit type.u— Unicode string (uCode,uName) — Voyager's Unicode-safe string variant, distinct from plains-prefixed strings.
One more worth flagging separately because it looks like a normal column and isn't: tRowVersion is a SQL Server rowversion/timestamp value, not a date — never treat it as one in a query.
h is the load-bearing prefix
If you're trying to understand how a table connects to the rest of the schema, the h-prefixed columns are where to look first. hMy is the near-universal primary key convention — when you see hMy on a table, that's almost always the row's own identity, and other tables will reference it. Every other h-prefixed column on that table is a candidate join path outward.
The naming inside the prefix usually tells you the target, too: hProp and hProperty both mean "foreign key to PROPERTY.hMy" — more on why there are two spellings below. hUnitType means a foreign key to UNITTYPE.hMy. The grammar is consistent enough that, most of the time, you can guess a foreign key's target from its name alone and confirm it with one lookup — instead of reverse-engineering the join from scratch.
Two generations of the same reference
Not every h-column follows a single spelling, and that's a real trap for anyone assuming a table's foreign-key name from a different table's convention. Both hProp and hProperty reference PROPERTY.hMy — they're the same relationship, spelled two different ways depending on when that part of the schema was built. hProp shows up on roughly 387 standard tables; hProperty on roughly 1,169. Older modules tend to carry the shorter form, newer modules the longer one.
The practical rule: don't assume a table's property foreign key is named one way because a different table's was. Check the specific table before writing the join — the grammar tells you it's a property reference either way, but the exact column name still varies table to table.
Audit columns look like business columns — they aren't
A huge share of Voyager tables — 2,000+ in the standard schema — carry a predictable set of h-prefixed audit columns: hUserCreatedBy, hUserModifiedBy, hUserCreated, hUserLastModified, hCreatedBy. All of them reference PMUSER.hMy, the user-account table.
These follow the same h-prefix grammar as any other foreign key, which is exactly why they're easy to mistake for business data. They aren't. They answer "who touched this row and when" — useful for a change-history question, never a legitimate join path for a business report. Pulling hUserModifiedBy into a rent roll query because it "looked like" a relevant handle is a fast way to produce a report about the wrong thing entirely.
The subtype trap: hMy isn't universal
The h-prefix grammar has one well-known exception worth knowing before it costs you a failed join: tables like TENANT, VENDOR, ROOM, and Customer are subtypes of a PERSON supertype, and their primary key isn't hMy — it's HMYPERSON. Foreign keys that reference them follow the target's real key name: hTenant and hVendor both point at HMYPERSON, not at a hMy column that, on these tables, doesn't exist. PROSPECT and PERSON itself are the exception to the exception — they do use hMy.
It's a small thing, but it's the difference between a join that runs and one that fails with a column-not-found error the first time you touch an unfamiliar person-subtype table.
Reading a table you've never seen before
Put the grammar to work and an unfamiliar table stops being a mystery:
- Scan for
hMy(orHMYPERSONif it looks like a person-subtype table) to confirm the primary key. - Scan the other
h-columns for join candidates — ignore thehUser*Created/Modifiedaudit set unless you're specifically asking about row history. - Use
i-prefixed columns as your discriminator/status fields — these are the ones worth decoding against an enum reference before you filter on them, not the ones to treat as freeform integers. - Treat
dt-columns as real dates,d-columns as amounts, and leavetRowVersionalone entirely.
That sequence takes under a minute on a table you've never opened, and it gets you most of the way to a correct first-draft query — before you've looked anything up externally.
One related pattern worth knowing on top of this grammar: some h-columns (hRecord, hCode, hParent) are polymorphic — the join target isn't fixed by the column name at all, but resolved row-by-row by a companion discriminator column. That's a big enough trap to deserve its own explanation.
Skip the memorization
Knowing the grammar gets you 80% of the way to reading Voyager fluently. The remaining 20% — which specific table a given h-column targets, whether it's one of the polymorphic exceptions, what its i-column's enum values actually decode to — is exactly what a schema reference is for.
PropETL's SQL Query Assistant carries this naming grammar, the H-prefix conventions, and the traps that come with them as part of a queryable knowledge base spanning 9,793 standard Voyager tables and 137,000+ columns — inside Claude, so you can ask about the table in front of you instead of guessing from the prefix alone.
Schema querying is included in every PropETL tier. Start the free 7-day trial — no credit card required — and try it on the next table that doesn't look like anything you've mapped before.
