内存中数据库中索引列的类型安全性
本文关键字:类型 类型安全 安全性 数据库 索引 内存 | 更新日期: 2023-09-27 17:59:13
问题的根源:我想设计一个数据库实体成员索引API,它不需要在模型定义中重复,并保持合理的类型安全级别。
详尽的解释:我有一个基本的人的记忆数据库。每个人都有一个全名和他们最喜欢的名人的钥匙。
public class IMDB
{
public Dictionary<int, Person> people;
}
public class Person
{
public string firstname;
public string lastname;
public int favoriteCelebrityID;
}
现在,名人们希望能够通过favoriteCelebrityID
快速找到他们的粉丝。一个索引是显而易见的,考虑到未来,我制作了这个界面:
public class IMDB
{
public Dictionary<int, Person> people;
private Dictionary<object, Dictionary<int, int>> _rowContents;
private Dictionary<object, Dictionary<int, List<int>>> _rowIndex;
// Returns the ID field in the given row.
public int RelatedID(int rowID, object field) { ... }
// Returns the ID of each rows with the given key in its field.
public List<int> IDRelatedIDs(int key, object field) { ... }
// Setter for the field. Maintains the index.
public void SetRelatedID(int rowID, int key, object field) { ... }
}
public class Person
{
public enum IndexedFields
{
FavoriteCelebrityID
}
public string firstName;
public string lastName;
}
我看到的好处:
- API级别的静态类型安全,除了通过
object
- 易于为任何新表中的索引键创建枚举
Person
模型中没有重复字段名称
但现在我也需要索引字符串lastName
,这样我就可以找到族。这就是我被卡住的地方。我的最佳想法是为每种数据类型实现三个索引方法:
public class IMDB
{
...
public int IDRelatedID(int rowID, object field) { ... }
public List<int> IDRelatedIDs(int key, object field) { ... }
public void SetRelatedID(int rowID, int key, object field) { ... }
public string IDRelatedString(int rowID, object field) { ... }
public List<int> StringRelatedIDs(string key, object field) { ... }
public void SetRelatedString(int rowID, string key, object field) { ... }
}
public class Person
{
public enum IndexedIDs
{
FavoriteCelebrityID
}
public enum IndexedStrings
{
LastName
}
public string firstName;
}
但现在有可能意外地将IndexedStrings
条目放入IDRelatedID
,这只能在运行时检测到。
是否有方法公开成员索引API:
- 模型定义中不需要重复吗
- 保持合理的类型安全水平
我对代理对象很谨慎,主要是出于效率方面的考虑,但解释如何制作高效代理的资源会很棒!
我可能已经使用泛型找到了一个好的解决方案:
public class IMDB
{
public Dictionary<int, Person> people;
public T RelatedID<T>(int id, IndexedMember<T> field) { ... }
public List<T> IDRelatedIDs<T>(int key, IndexedMember<T> field) { ... }
public void SetRelatedID<T>(int id, T newVal, IndexedMember<T> field) { ... }
}
public class Person
{
// "new IndexedMember<int>()" to initialize before first access, or
// init upon startup (using some other manifest already maintained)
// for less verbosity.
public static IndexedMember<int> favoriteCelebrityID;
public static IndexedMember<string> lastName;
public string firstName;
}
public class IndexedMember<T>
{
// ...
}
如果我能实现这一点,我会非常满意,但任何改进或替代解决方案都是受欢迎的。