4.4 序号化

主键是自然数序号的维表,可以直接用序号定位实现关联,不必建索引,避免计算和比对 HASH 值,性能更好。

主键不是自然数序号的维表,可以事先转换成序号。同时把事实表中的对应维字段值也转换成相应的序号后,就可以也使用序号定位。

4.4.1 主键是自然数序号的维表

SQL

SELECT Employees.Region,sum(Orders.Amount)
FROM Orders
LEFT JOIN Employees	ON Orders.EmployeeID=Employees.EmployeeID
WHERE OrderDate>='2021-01-01' and OrderDate<='2021-12-31' 
GROUP BY Employees.Region

SPL

A
1 >st=date(“2021-01-01”), et=date(“2021-12-31”), start=days@o(st), end=days@o(et)
2 >Employees=file(“Employees.btx”).import@b()
3 =file(“Orders_Time.ctx”).open().cursor@mx(EmployeeID,Amount;OrderDate>=start && OrderDate<=end)
4 =A3.switch(EmployeeID,Employees:#)
5 =A4.groups(EmployeeID.Region;sum(Amount):Amount)

A2 注意:因为 EmployeeID 本身是自然数序号,所以转储 Employees.btx 时按 EmployeeID 排序,读入时不必再建主键索引
A4 采用序号的方式关联 Employees 维表

4.4.2 主键不是自然数序号的维表

SQL

SELECT Products.ProductName, sum(Orders.Quantity)
FROM Orders
LEFT JOIN Products ON Orders.ProductID=Products.ProductID
WHERE OrderDate>='2021-01-01' and OrderDate<='2021-12-31' 
GROUP BY Products.ProductName

SPL

Orders_Time.ctx 文件准备代码,将 ProductID 改成序号

A
1 >Products=file(“Products.btx”).import@b().keys@i(ProductID)
2 =file(“Orders_Time.ctx”).open().cursor@mx()
3 =A2.run(ProductID=Products.pfind(ProductID))
4 =file(“Orders_Time_P.ctx”).create@y(#OrderDate, CustomerID, ProductID, Quantity, Unit, Price, Amount, EmployeeID,EmployeeName,ShipVia)
5 =A4.append(A3)
6 >A4.close()

A1 读取 Products 维表至内存,设置主键索引
A3 把 Orders 表的 ProductID 字段值变成其在维表中的序号
A4 创建新的组表(和原组表字段顺序一致)
A5 把 Orders 表的数据写入组表文件

统计:

A
1 >st=date(“2021-01-01”), et=date(“2021-12-31”), start=days@o(st), end=days@o(et)
2 >Products=file(“Products.btx”).import@b()
3 =file(“Orders_Time_P.ctx”).open().cursor@x(ProductID,Quantity; OrderDate >=start && OrderDate <=end)
4 =A3.switch(ProductID,Products:#)
5 =A4.groups(ProductID.ProductName; sum(Quantity):Quantity)

A2 读产品维表时不用再建主键索引
A4 采用序号方式关联