views:

372

answers:

7

A table's boolean fields can be named using the positive vs the negative...

for example, calling a field:

"ACTIVE" , 1=on / 0=off 
or
"INACTIVE" , 0=on / 1=off


Question: Is there a proper way to make this type of table design decision, or is it arbitrary?


My specific example is a messages table with a bool field (private/public). This field will be set using a form checkbox when a user enters a new message. Is there a benefit in naming the field "public" vs "private"?

thanks.

+12  A: 

I always prefer positive names, to avoid double negatives in code. "Is not inactive" is often cause for a double take when reading. "Is inactive" can always be written as "if (!Active)" whilst taking advantage of built-in language semantics.

Adam Wright
+9  A: 

My personal preference:

  • Use prefixes like "Is", "Has", etc. for Boolean fields to make their purpose clear.
  • Always name variables in the affirmative. For Active/Inactive, I would name it IsActive.
  • Don't make a bit field nullable unless you really have a specific purpose in doing so.

In your specific use case, the field should be named either IsPublic or IsPrivate--whichever name would result in a True answer when the user ticks the checkbox.

richardtallent
+1 for "checkbox true" equaling "database true"
Ben Blank
...and what about built-in negatives of the design like "Lockout line"?The device is inactive if the lockout line is high. isLockedOut means pretty much isDeviceInactive. But when I test the lockout line, I'm interested in isLockoutActive...or, isWorkingCorrectly or isInFaultMode?
SF.
A: 

Always use positive names.

If use negative names, you very quickly get into double negation. Not that double negation is rocket surgery, but it's a brain cycle and those are valuable :)

Stefan
A: 

Always use positive.

It's simpler.

Take using the negation to the logical extreme: if InActive is better than Active, then why not InInActive, or InInInActive?

Because it would be less simple.

Larry Watanabe
+1  A: 

The proper way to handle these situations is to create a table to house the values associated with the column, and create a foreign key relationship between the two tables. IE:

WIDGETS table:

  • WIDGET_ID
  • WIDGET_STATUS (fk)

WIDGET_STATUS_CODES table:

  • WIDGET_STATUS_CODE (pk)
  • DESCRIPTION

If possible, WIDGET_STATUS_CODE would be a natural key (IE: ACT for "Active", INA for "Inactive"). This would make records more human readable, but isn't always possible so you'd use an artificial/surrogate key (like an auto-number/sequence/etc).

You want to do this because:

  • It's readable what status indicates (which was the original question)
  • Future proof in the need to define/use more statuses
  • Provides referencial integrity so someone couldn't set the value to 2, 3, 4, etc.
  • Space is cheap; there's nothing efficient about allowing bad data
OMG Ponies
This is FAR less efficient than a simple bit field. What is the justification for doing this versus a simple bit field for a simple Boolean answer?
richardtallent
(a) Human readability of bare tables is not, IMHO, a goal of good database design. Otherwise, we would never use surrogate keys, and our databases would spend their entire lives doing string comparisons.
richardtallent
(b) I agree in principle w/r/t future-proofing for more values, but ONLY if there is a possible status that is NEITHER of the existing choices.Naming a field something generic like "Status" when it really has to do *only* with Active/Inactive mode invites future abuse by shoehorning orthogonal attributes.Eventually, this forces the design toward a m:n relationship that resembles a loosely-typed tag cloud. I'm not against tag clouds in general, but they break normalization, and that has consequences for the design.
richardtallent
(c) referential integrity is not needed for a Boolean/bit field, since the list of values is already restricted to 1/0.
richardtallent
+1, I tend to avoid bit data types, unless you have a table with many true/false flags that can't be combined into one status flag. A single bit column in a table will still take a byte to store it. I'll just use a check constraint if it is Status="A"ctive-"I"nactive, but use a FK and a table if you have more and/or strange values like "Q", etc.
KM
(d) Space is cheap, but string comparisons are not, and neither are joins, especially when the number of potential values is two.
richardtallent
KM, a single bit field does *not* take a byte in MSSQL, unless it is the *only* bit field in the table. Not that 7 bits would be a huge waste, but just sayin'... Using varchar() fields with check constraints or foreign keys to other tables to store mere Boolean values is, IMHO, madness.
richardtallent
@richardtallent, calm down. I said: _A single bit column in a table will still take a byte to store it_ which is 100% true. Also, I never said that a Status column should be varchar(); a char(1) does just fine. I've seen many people use the bit column very poorly. They make multiple true/false columns to track a status, like for an invoice: isValid, isPaid, isPosted, isComplete; where a single status column with values "V", "P", "O", "C" and a FK to descriptive table works much better for me makes all the code simple one field to track status, not multiple.
KM
@KM: Missed your point about bit--sorry. But using a char(1) as you've described only works if the values are **dependent**. Many times, database designers make the mistake of rolling independent status fields together by designing for an *ideal* workflow (e.g,assuming that isPosted implies isPaid, etc.). When a record in the real world jumps around, skips steps, etc., you lose important information. But my issue is specifically with implementing truly Boolean fields this way--a flexible design is good, but IMHO this breaks YAGNI and should not be a rule of thumb.
richardtallent
+1  A: 

i would not disagree with some of the other answers but definitely avoid the incorrect answer which is not to put in double negatives always

ooo
A: 

Try to avoid boolean fields in databases alltogether.

One, the RM has a much better way to represent truth-valued information than via boolean fields : via the presence of a tuple in a table.

Two, boolean fields are very bad discriminators when querying. It's virtually complete madness to index them, so when querying, the presence of boolean fields gives no benefit at all.

Erwin Smout
Boolean values can be poor discriminators, but that depends *entirely* on the distribution of 0 and 1 values.Like any index, indexing a bit field adds an element of table lookup indirection if it is not the first-order column in a clustered index (which I'm not recommending), but indexing *does* avoid a table scan, so there *is* a performance benefit.Meanwhile, using a FK to another table with a single value has exactly the performance limitation as an indexed bit field, and for the same reason, but joins add substantial additional overhead versus a bit index lookup.
richardtallent