# 最佳实践

**URL:** https://heroiclabs.com/docs/zh/nakama/concepts/friends/best-practices/
**Summary:** 好友关系是当代在线游戏的核心，Nakama功能集和API可帮助您在游戏中建立沉浸式好友体验。了解这些功能的运作原理及其最佳实现方式。

---


# 好友最佳实践

好友关系是当代在线游戏的核心。Nakama功能集和API可帮助您在游戏中建立沉浸式好友体验。

追求纯粹独处的游戏越来越少。游戏是一种社交体验，在游戏里可以和多年好友组队，也可以和新对手互相调侃。作为开发人员，创造沉浸式体验需要灵活、高性能的系统来表现玩家的社交关系。在Nakama中，[好友](../)是一个核心系统。

本页详细介绍了Nakama如何表现好友关系（既作为概念，也作为数据结构），好友关系的重要意义，以及充分利用Nakama好友系统的指导原则。

## 关系建模

Nakama有其灵活的好友关系模型，可以表现多种不同的关系状态，并利用高效、可扩展的方法存储。

受Twitter的[FlockDB](https://github.com/twitter-archive/flockdb#flockdb)启发，在Nakama中，这些关系的概念基础构成了有向图的边缘。

例如，假设有两位玩家A和B。如果A和B是好友，那么他们的关系可以表示为边缘AB（“A是B的好友”）和BA（“B是A的好友”）。

![玩家A和B的关系](images/graph.png)

## 关系状态

两个人之间的关系比他们之间仅仅存在联系更加丰富。在Nakama好友系统中，两个玩家之间的每种关系（边缘）都有一个状态：已接受好友关系、等待接受好友关系、或已屏蔽。当两个玩家之间没有关系时，他们之间便没有边缘。

Nakama可以表笑以下基本关系状态：

- **无关系**：两个玩家之间没有边缘
- **非对称关系**：一个玩家向另一个玩家发出的等待接受的好友请求
- **对称好友关系**：两个玩家是共同好友
- **消极关系**：一位玩家已屏蔽另一位玩家

将Nakama好友系统看作任意两个玩家之间的状态机。玩家可以通过明确定义的路径从一个状态转至下一个状态。以下是两个玩家之间关系的潜在状态图：

![关系状态](images/relationships.svg)

这种好友关系的表示不仅处理游戏中使用的最常见的好友模型，而且具有高效存储和查询的优势。

## 存储关系

Nakama数据库使用了一种小规模、易于理解的好友关系状态表示方法。这种表示方法经过微调，可快速、高效、可扩展地完成最常见的任务，例如查找用户的所有关系。

为了更好地理解Nakama存储模型，需要检查数据库架构中使用的主键。这包括：

- 玩家ID (`source_id`)
- 关系的状态 (`state`)
- 计数器 (`position`)

主键是指将每个玩家的关系物理存储到磁盘上，靠近该玩家的其他关系。主键是指将每个玩家的关系物理存储到磁盘上，靠近该玩家的其他关系。

| `source_id`                          | `state` | `position` |
|--------------------------------------|---------|------------|
| ...                                  | ...     | ...        |
| 4246fc0f-a55f-45da-9b25-8527c2a0d5d1 | 0       | 7684       |
| 4246fc0f-a55f-45da-9b25-8527c2a0d5d1 | 0       | 7697       |
| 4246fc0f-a55f-45da-9b25-8527c2a0d5d1 | 1       | 7694       |
| ...                                  | ...     | ...        |

换言之，玩家的共同好友与他们的其他共同好友、等待接受的邀请和其他内容一起被记录下来。

从物理数据库的角度来看，这种布局适合最常见的查询。例如，如果您查询一个给定玩家的所有关系（即 `SELECT * from user_edge WHERE source_id=player_a_id`)，可以查询连续的行，这可以最大限度地减少数据库的检索时间。

如果数据库不能自动获取此项便利，索引会加速查找。查询两个特定用户之间的关系（即两个已知玩家ID之间的关系）有专门的索引。

## 可扩展性

除了物理数据库的便利之外，好友架构还可以通过允许您将您的好友数据分布到您的播放器附近的位置，从而扩展到全球受众。

Nakama分别代表好友关系的双方。会记录“玩家A是玩家B的好友”，也会记录“玩家B是玩家A的好友”。如果您将数据库进行地理分区，即将好友数据存储在距离您的播放器最近的实例上，那么查询就不仅仅是在磁盘上进行，也会在距离您的播放器更近的硬件上进行。

## 开发最佳实践

Nakama的好友模型旨在让您的游戏不断更加容易开发和成长。遵循这些最佳实践，充分发挥它们的作用。

### 节省开发人员资源

没有必要重新设计您自己的基元来表示好友关系。Nakama提供了您需要的许多API和数据结构，用来表示游戏的社交连接。随着您的扩展，您可能会发现很难将自定义实施方式重新改造回Nakama的系统中。

### 节省集群资源

与开发人员的时间一样，您的基础设施资源也是有限的。Heroic Labs已经调整了好友系统，使其能够得当扩大和缩小，智能阅读、编写和使用好友关系。

### 创建丰富的互动关系

您可能已经注意到，我们没有提到社交网络帐户、单点登录或其他集成。Nakama的好友系统旨在成为游戏中社交关系的基石，而不是整个结构的基石。

是否要与[社交供应商](../../authentication/#social-providers)同步？按好友过滤[排行榜](../../leaderboards/#list-by-friends)？创建好友聊天群组？为此，您可以将好友系统与Nakama的其他系统或第三方API进行合成。
