KDB+枚举仅存键引用未存储键的机制疑问及加载异常咨询
Let's break down your questions about KDB+ enums step by step, using your examples as reference:
1. Why can't I create an enum directly with a list like :`a`b`c$`b`a`c`c`a`b?
The syntax x$y has two distinct behaviors depending on what x represents:
- If
xis an atomic type (likeint,symbol, etc.), it convertsyto that type. - If
xis a symbol referencing a named key list (likemykeys), it creates an enum mapped to that key list.
When you write :`a`b`c$`b`a`c`c`a`b, KDB+ treats :`a`b`c as a regular symbol list and tries to perform a type conversion—not enum creation. Since the length of your source list (6) doesn't match the target list (3), you get the 'length error.
To create an enum properly, first assign your key list to a named variable, then reference that variable's symbol in the conversion:
q)mykeys:`a`b`c q)e:`mykeys$`b`a`c`c`a`b // Works because `mykeys` points to the named key list `mykeys$`b`a`c`c`a`b
2. Why isn't the key list saved when I store the enum to a file?
Enums in KDB+ are fundamentally labeled integer lists. The "label" is just the symbol name of your key list (e.g., mykeys), not the actual values of the key list itself. When you save an enum with set, KDB+ only stores:
- The label symbol (
mykeys) - The integer indices mapped to your values
This design is all about efficiency:
- Storing integers instead of full symbols saves massive space, especially for large datasets.
- If multiple enums or tables share the same key list, you don't need to duplicate the key data—you just reference the same named variable.
3. Why does the enum still exist after loading it without the key list defined?
What you're seeing is a "dangling enum"—a semi-valid state where KDB+ retains the label and index data even if the key list variable doesn't exist yet. When you load the enum without mykeys defined, KDB+ displays it as a dictionary:
q)e: get `:e.raw q)e `mykeys!1 0 2 2 0 1
This is intentional flexibility:
- You can load the enum data first, then define the key list later to resolve the mapping.
- You can even replace the
mykeysvariable with a different list to remap indices to new values (though this is usually not recommended unless you know exactly what you're doing).
Once you define the mykeys variable, KDB+ automatically resolves the indices back to the key values, restoring the normal enum display.
4. Why are enums designed this way?
The separation of keys and enum values is optimized for performance and scalability, especially in database use cases:
- Table efficiency: Enums let you store repeated symbol values as tiny integers in tables, reducing storage size and speeding up sorting/filtering operations.
- Shared dimensions: In data warehouses or split tables, multiple tables can reference the same key list (e.g., a
product_codesenum used across sales, inventory, and shipping tables). Update the key list once, and all enums referencing it will automatically use the new values. - Indexing: Enums play nicely with KDB+'s indexing capabilities—integer indices are faster to index and query than full symbols.
If you want to save the key list along with the enum, use the enum extension syntax you mentioned:
q)`:mykeys?`b`a`c`c`a`b; // Saves both the key list and enum indices q)get `:mykeys `b`a`c
This stores the key list in the file, so when you load it later, the key list is restored automatically.
内容的提问来源于stack exchange,提问作者egor7

