

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# Amazon Neptune 功能概觀
<a name="feature-overview"></a>

**注意**  
本節未涵蓋使用您可以用來存取 Neptune 圖形中資料的查詢語言。  
如需如何使用 Gremlin 連線到執行中 Neptune 資料庫叢集的相關資訊，請參閱 [使用 Gremlin 存取 Neptune 圖形](access-graph-gremlin.md)。  
如需如何使用 openCypher 連線到執行中 Neptune 資料庫叢集的相關資訊，請參閱 [使用 openCypher 存取 Neptune 圖形](access-graph-opencypher.md)。  
如需如何使用 SPARQL 連線到執行中 Neptune 資料庫叢集的相關資訊，請參閱 [使用 SPARQL 存取 Neptune 圖形](access-graph-sparql.md)。

本節提供特定 Neptune 功能的概觀，包括：
+ [Neptune 符合查詢語言標準](feature-overview-standards-compliance.md)。
+ [Neptune 的圖形資料模型](feature-overview-data-model.md)。
+ [Neptune 交易語義的說明](transactions.md)。
+ [Neptune 叢集和執行個體簡介](feature-overview-db-clusters.md)。
+ [Neptune 的儲存體、可靠性和可用性](feature-overview-storage.md)。
+ [Neptune 端點的說明](feature-overview-endpoints.md)。
+ [使用 Neptune 的*實驗室模式*啟用實驗功能](features-lab-mode.md)。
+ [Neptune DFE 引擎的描述](neptune-dfe-engine.md)。
+ [Neptune 的 JDBC 連線能力](neptune-jdbc.md)。
+ [Neptune 引擎版本清單以及如何更新引擎](engine-releases.md)。

# Amazon Neptune 標準合規的注意事項
<a name="feature-overview-standards-compliance"></a>

在大多數情況下，Amazon Neptune 符合實作 Gremlin 和 SPARQL 圖形查詢語言的適用標準。

以下各節說明這些標準，以及 Neptune 擴展或從中分出來的領域。

**Topics**
+ [Amazon Neptune 中的 Gremlin 標準合規](access-graph-gremlin-differences.md)
+ [Amazon Neptune 中的 SPARQL 標準合規](feature-sparql-compliance.md)
+ [Amazon Neptune 中的 openCypher 規格合規](feature-opencypher-compliance.md)

# Amazon Neptune 中的 Gremlin 標準合規
<a name="access-graph-gremlin-differences"></a>

以下各節提供 Gremlin 的 Neptune 實作概觀，以及其與 Apache TinkerPop 實作的差異。

Neptune 會在其引擎中以原生方式實作一些 Gremlin 步驟，並使用 Apache TinkerPop Gremlin 實作來處理其他步驟 (請參閱 [Amazon Neptune 的原生 Gremlin 步驟支援](gremlin-step-support.md))。

**注意**  
如需 Gremlin 主控台和 Amazon Neptune 中所顯示實作差異的一些具體範例，請參閱快速入門的 [使用 Gremlin 存取 Amazon Neptune 中的圖形資料](get-started-graph-gremlin.md) 一節。

**Topics**
+ [Gremlin 的適用標準](#feature-gremlin-applicable-standards)
+ [指令碼中的變數和參數](#feature-gremlin-differences-variables)
+ [TinkerPop 列舉](#feature-gremlin-differences-tinkerpop)
+ [Java 程式碼](#feature-gremlin-differences-java)
+ [元素上的屬性](#feature-gremlin-differences-properties-on-elements)
+ [指令碼執行](#feature-gremlin-differences-script)
+ [工作階段](#feature-gremlin-differences-sessions)
+ [交易](#feature-gremlin-differences-transactions)
+ [頂點和邊緣 ID](#feature-gremlin-differences-vertex-edge-ids)
+ [使用者提供的 ID](#feature-gremlin-differences-user-supplied-ids)
+ [頂點屬性 ID](#feature-gremlin-differences-vertex-property-ids)
+ [頂點屬性的基數](#feature-gremlin-differences-vertex-property-cardinality)
+ [更新頂點屬性](#feature-gremlin-differences-vertex-property-update)
+ [標籤](#feature-gremlin-differences-labels)
+ [逸出字元](#feature-gremlin-differences-escapes)
+ [Groovy 限制](#feature-gremlin-differences-groovy)
+ [序列化](#feature-gremlin-differences-serialization)
+ [Lambda 步驟](#feature-gremlin-differences-lambda)
+ [不支援的 Gremlin 方法](#feature-gremlin-differences-unsupported-methods)
+ [不支援的 Gremlin 步驟](#feature-gremlin-differences-unsupported-steps)
+ [Neptune 中的 Gremlin 圖形功能](#gremlin-api-reference-features)

## Gremlin 的適用標準
<a name="feature-gremlin-applicable-standards"></a>
+ Gremlin 語言是由 [Apache TinkerPop Documentation](http://tinkerpop.apache.org/docs/current/reference/) 和 Gremlin 的 Apache TinkerPop 實作定義，而不是由型式規格定義。
+ 對於數值格式，Gremlin 遵循 IEEE 754 標準 ([IEEE 754-2019 - 浮點數運算的 IEEE 標準](https://standards.ieee.org/content/ieee-standards/en/standard/754-2019.html)。如需詳細資訊，另請參閱 [Wikipedia IEEE 754 頁面](https://en.wikipedia.org/wiki/IEEE_754))。

## 指令碼中的變數和參數
<a name="feature-gremlin-differences-variables"></a>

如果與預先繫結的變數有關，則周遊物件 `g` 在 Neptune 中是預先繫結的，而且不支援 `graph` 物件。

雖然 Neptune 不支援指令碼中的 Gremlin 變數或參數化，但是您可能經常會在網際網路上遇到 Gemlin 伺服器的範例指令碼，其中包含變數宣告，例如：

```
String query = "x = 1; g.V(x)";
List<Result> results = client.submit(query).all().get();
```

在提交查詢時，還有許多使用[參數化](https://tinkerpop.apache.org/docs/current/reference/#parameterized-scripts) (或繫結) 的範例，例如：

```
Map<String,Object> params = new HashMap<>();
params.put("x",1);
String query = "g.V(x)";
List<Result> results = client.submit(query).all().get();
```

參數範例通常與警告相關聯，這些警告關於盡可能不參數化所產生的效能損失。對於 TinkerPop，您可能會遇到很多這樣的範例，而且關於需要參數化，它們聽起來都非常有說服力。

不過，變數宣告功能和參數化功能 (以及警告) 只在使用 `GremlinGroovyScriptEngine` 時才適用於 TinkerPop 的 Grimlin 伺服器。當 Gremlin 伺服器使用 Gramlin 的 `gremlin-language` ANTLR 文法來解析查詢時，它們不適用。ANTLR 語法不支援變數宣告或參數化，因此在使用 ANTLR 時，您不必擔心無法參數化。因為 ANTLR 文法是 TinkerPop 的較新元件，因此您在網際網路上可能遇到的較舊內容通常不會反映這種差異。

Neptune 會在其查詢處理引擎中使用 ANTLR 文法，而不是 `GremlinGroovyScriptEngine`，因此它不支援變數或參數化或 `bindings` 屬性。因此，與無法參數化有關的問題不適用於 Neptune。使用 Neptune，只需在通常參數化的位置按原狀提交查詢就非常安全。因此，前面的範例可以簡化，而不會造成任何效能損失，如下所示：

```
String query = "g.V(1)";
List<Result> results = client.submit(query).all().get();
```

## TinkerPop 列舉
<a name="feature-gremlin-differences-tinkerpop"></a>

Neptune 不支援列舉值的完全合格類別名稱。例如，您必須在 Groovy 請求中使用 `single`，而不是 `org.apache.tinkerpop.gremlin.structure.VertexProperty.Cardinality.single`。

列舉類型由參數類型決定。

下表顯示允許的列舉值和相關的 TinkerPop 完全合格名稱。

| 允許值 | 類別 | 
| --- |--- |
| id, 金鑰, label, value | [org.apache.tinkerpop.gremlin.structure.T](https://tinkerpop.apache.org/javadocs/current/core/org/apache/tinkerpop/gremlin/structure/T.html) | 
| T.id, T.key, T.label, T.value | [org.apache.tinkerpop.gremlin.structure.T](https://tinkerpop.apache.org/javadocs/current/core/org/apache/tinkerpop/gremlin/structure/T.html) | 
| set, single | [org.apache.tinkerpop.gremlin.structure.VertexProperty.Cardinality](https://tinkerpop.apache.org/javadocs/current/core/org/apache/tinkerpop/gremlin/structure/VertexProperty.Cardinality.html) | 
| asc, desc, shuffle | [org.apache.tinkerpop.gremlin.process.traversal.Order](https://tinkerpop.apache.org/javadocs/3.7.2/full/org/apache/tinkerpop/gremlin/process/traversal/Order.html) | 
| Order.asc, Order.desc, Order.shuffle | [org.apache.tinkerpop.gremlin.process.traversal.Order](https://tinkerpop.apache.org/javadocs/3.7.2/full/org/apache/tinkerpop/gremlin/process/traversal/Order.html) | 
| 全域, 本機 | [org.apache.tinkerpop.gremlin.process.traversal.Scope](https://tinkerpop.apache.org/javadocs/3.7.2/core/org/apache/tinkerpop/gremlin/process/traversal/Scope.html) | 
| Scope.global, Scope.local | [org.apache.tinkerpop.gremlin.process.traversal.Scope](https://tinkerpop.apache.org/javadocs/3.7.2/core/org/apache/tinkerpop/gremlin/process/traversal/Scope.html) | 
| 全部, first, last, mixed | [org.apache.tinkerpop.gremlin.process.traversal.Pop](https://tinkerpop.apache.org/javadocs/3.7.2/core/org/apache/tinkerpop/gremlin/process/traversal/Pop.html) | 
| normSack | [org.apache.tinkerpop.gremlin.process.traversal.SackFunctions.Barrier](https://tinkerpop.apache.org/javadocs/3.7.2/core/org/apache/tinkerpop/gremlin/process/traversal/SackFunctions.Barrier.html) | 
| addAll, 及, assign, div, max, min, minus, mult, 或, sum, sumLong | [org.apache.tinkerpop.gremlin.process.traversal.Operator](https://tinkerpop.apache.org/javadocs/3.7.2/core/org/apache/tinkerpop/gremlin/process/traversal/Operator.html) | 
| keys, values | [org.apache.tinkerpop.gremlin.structure.Column](https://tinkerpop.apache.org/javadocs/3.7.2/core/org/apache/tinkerpop/gremlin/structure/Column.html) | 
| BOTH, IN, OUT | [org.apache.tinkerpop.gremlin.structure.Direction](https://tinkerpop.apache.org/javadocs/3.7.2/core/org/apache/tinkerpop/gremlin/structure/Direction.html) | 
| any, 無 | [org.apache.tinkerpop.gremlin.process.traversal.step.TraversalOptionParent.Pick](https://tinkerpop.apache.org/javadocs/current/full/org/apache/tinkerpop/gremlin/process/traversal/Pick.html) | 

## Java 程式碼
<a name="feature-gremlin-differences-java"></a>

Neptune 不支援任意 Java 所定義以外的呼叫方法或除了支援的 Gremlin API 以外的 Java 程式庫呼叫。例如，不允許 `java.lang.*`、`Date()` 和 `g.V().tryNext().orElseGet()`。

## 元素上的屬性
<a name="feature-gremlin-differences-properties-on-elements"></a>

 Neptune 不支援在 TinkerPop 3.7.0 中引入的`materializeProperties`旗標，以傳回元素上的屬性。因此，Neptune 仍然只會傳回頂點或邊緣做為參考，只有其 `id`和 `label`。

## 指令碼執行
<a name="feature-gremlin-differences-script"></a>

所有查詢開頭必須為周遊物件 `g`。

在字串查詢提交中，您可以發出多重周遊，並以分號 (`;`) 或換行符號字元 (`\n`) 分隔。若要執行，除了最後一個以外的每個陳述式結尾必須是 `.iterate()` 步驟。只有最後的周遊資料會傳回。請注意，這不適用於 GLV ByteCode 查詢提交。

## 工作階段
<a name="feature-gremlin-differences-sessions"></a>

Neptune 中的工作階段僅限持續 10 分鐘。如需更多資訊，請參閱 [Gremlin 指令碼型工作階段](access-graph-gremlin-sessions.md)和 [TinkerPop 工作階段參考](https://tinkerpop.apache.org/docs/current/reference/#console-sessions)。

## 交易
<a name="feature-gremlin-differences-transactions"></a>

Neptune 會在每個 Gremlin 周遊開始時開啟新交易，並在周遊成功完成時關閉交易。發生錯誤時交易將還原。

 以分號 (`;`) 或換行符號字元 (`\n`) 分隔的多重陳述式包含在單一交易內。除了最後一個以外的每個陳述式結尾必須為要執行的 `next()` 步驟。只有最後的周遊資料會傳回。

使用 `tx.commit()` 和 `tx.rollback()` 的手動交易邏輯不受支援。

**重要**  
這「只」******適用於以「文字字串」******傳送 Gremlin 查詢的方法 (請參閱 [Gremlin 交易](access-graph-gremlin-transactions.md))。

## 頂點和邊緣 ID
<a name="feature-gremlin-differences-vertex-edge-ids"></a>

Neptune Gremlin 頂點和邊緣 ID 必須為 `String` 類型。這些 ID 字串支援 Unicode 字元，且大小不能超過 55 MB。

使用者提供的 ID 受到支援，但它們在正常使用狀況下為選用。如果您在新增頂點或邊緣時未提供 ID，Neptune 會產生 UUID 並將其轉換為字串，格式如下：`"48af8178-50ce-971a-fc41-8c9a954cea62"`。這些 UUID 不符合 RFC 標準，因此，如果您需要標準 UUID，則應在外部產生它們，並在您新增頂點或邊緣時提供它們。

**注意**  
不過，Neptune `Load` 命令要求您使用 Neptune CSV 格式的 **\$1id** 欄位提供 ID。

## 使用者提供的 ID
<a name="feature-gremlin-differences-user-supplied-ids"></a>

使用者提供的 ID 允許使用在 Neptune Gremlin，條文如下。
+ 提供的 ID 是選用的。
+ 僅支援頂點和邊緣。
+ 僅支援 `String` 類型。

若要建立使用自訂 ID 的新頂點，請使用 `property` 步驟搭配 `id` 關鍵字：`g.addV().property(id, 'customid')`。

**注意**  
 不要將引號放在 `id` 關鍵字旁邊。它指的是 `T.id`。

所有的頂點 ID 必須各不相同，且所有的邊緣 ID 必須各不相同。不過，Neptune 確實允許頂點和邊緣具有相同的 ID。

如果您嘗試使用 `g.addV()` 建立新頂點，而使用該 ID 的頂點已存在，則操作會失敗。例外狀況為，如果您為頂點指定新的標籤，操作即會成功，但會將新標籤及指定的任何其他屬性新增至現有的頂點。不會覆寫任何項目。此舉不會建立新的頂點。頂點 ID 將維持不變，仍保有其唯一性。

例如，以下的 Gremlin 主控台命令會成功：

```
gremlin> g.addV('label1').property(id, 'customid')
gremlin> g.addV('label2').property(id, 'customid')
gremlin> g.V('customid').label()
==>label1::label2
```

## 頂點屬性 ID
<a name="feature-gremlin-differences-vertex-property-ids"></a>

Vertex 屬性 ID 將自動產生，且查詢時可顯示為正數或負數。

## 頂點屬性的基數
<a name="feature-gremlin-differences-vertex-property-cardinality"></a>

Neptune 支援成組基數和單一基數。如未指定，則選取設定基數。這表示，如果您設定屬性值，它將新增新的值至屬性，但前提是其不能出現在值組內。此為 [Set](https://tinkerpop.apache.org/javadocs/3.7.2/core/org/apache/tinkerpop/gremlin/structure/VertexProperty.Cardinality.html) 的 Gremlin 列舉值。

不支援 `List`。如需屬性基數的詳細資訊，請參閱 Gremlin JavaDoc 中的 [Vertex](https://tinkerpop.apache.org/javadocs/3.7.2/core/org/apache/tinkerpop/gremlin/structure/Vertex.html#property-org.apache.tinkerpop.gremlin.structure.VertexProperty.Cardinality-java.lang.String-V-java.lang.Object...-) 主題。

## 更新頂點屬性
<a name="feature-gremlin-differences-vertex-property-update"></a>

若要更新屬性值，而不新增額外的值給值組，請在 `property` 步驟中指定 `single` 基數。

```
g.V('exampleid01').property(single, 'age', 25)
```

這會移除屬性所有現有的值。

## 標籤
<a name="feature-gremlin-differences-labels"></a>

Neptune 支援頂點的多個標籤。當您建立標籤時，您可以指定多重標籤並用 `::` 分隔。例如，`g.addV("Label1::Label2::Label3")` 將新增有三種不同標籤的頂點。`hasLabel` 步驟將比對此頂點和這三個標籤：`hasLabel("Label1")`、`hasLabel("Label2")` 和 `hasLabel("Label3")`。

**重要**  
`::` 分隔符號僅針對本用途保留。您不能在 `hasLabel` 步驟中指定多重標籤。例如，`hasLabel("Label1::Label2")` 不符合任何內容。

## 逸出字元
<a name="feature-gremlin-differences-escapes"></a>

Neptune 會解析所有逸出字元，如 Apache Groovy 語言文件的[逸出特殊字元]( http://groovy-lang.org/syntax.html#_escaping_special_characters)一節所述。

## Groovy 限制
<a name="feature-gremlin-differences-groovy"></a>

Neptune 不支援開頭不是 `g` 的 Groovy 命令。這包括數學 (例如 `1+1`)、系統呼叫 (例如 `System.nanoTime()`) 和變數定義 (例如 `1+1`)。

**重要**  
Neptune 不支援完整的類別名稱。例如，您必須在 Groovy 請求中使用 `single`，而不是 `org.apache.tinkerpop.gremlin.structure.VertexProperty.Cardinality.single`。

## 序列化
<a name="feature-gremlin-differences-serialization"></a>

Neptune 根據請求的 MIME 類型支援下列序列化。

 Neptune 會公開 TinkerPop 執行的所有序列化程式，並支援 GraphSON 和 GraphBinary 的各種版本和組態。雖然存在許多選項，但使用 的指引非常簡單：
+  如果您使用的是 Apache TinkerPop 驅動程式，則偏好驅動程式的預設值，而不明確指定一個驅動程式。除非您有非常具體的原因，否則您可能不需要在驅動程式初始化中指定序列化程式。一般而言，驅動程式使用的預設值為 `application/vnd.graphbinary-v1.0`。
+  如果您是透過 HTTP 連線至 Neptune，請優先使用 `application/vnd.gremlin-v3.0+json;types=false`做為替代 GraphSON 3 版本中的內嵌類型，讓使用 變得複雜。
+  通常只有在與 [Gremlin 主控台](https://docs.aws.amazon.com//neptune/latest/userguide/access-graph-gremlin-console.html)搭配使用時`application/vnd.graphbinary-v1.0-stringd`才有用，因為它會將所有結果轉換為字串表示法以進行簡單顯示。
+  由於傳統原因，其餘格式仍然存在，通常不應在沒有明確原因的情況下與驅動程式搭配使用。

|  |  |  | 
| --- |--- |--- |
| MIME type | Serialization | Configuration | 
| `application/vnd.gremlin-v1.0+json` | GraphSONMessageSerializerV1 | ioRegistries：【org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerIoRegistryV1】 | 
| `application/vnd.gremlin-v1.0+json;types=false` | GraphSONUntypedMessageSerializerV1 | ioRegistries：【org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerIoRegistryV1】 | 
| `application/vnd.gremlin-v2.0+json` | GraphSONMessageSerializerV2 | ioRegistries：【org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerIoRegistryV2】 | 
| `application/vnd.gremlin-v2.0+json;types=false` | GraphSONUntypedMessageSerializerV2 | ioRegistries：【org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerIoRegistryV2】 | 
| `application/vnd.gremlin-v3.0+json` | GraphSONMessageSerializerV3 | ioRegistries：【org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerIoRegistryV3】 | 
| `application/vnd.gremlin-v3.0+json;types=false` | GraphSONUntypedMessageSerializerV3 | ioRegistries：【org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerIoRegistryV3】 | 
| `application/json` | GraphSONUntypedMessageSerializerV3 | ioRegistries：【org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerIoRegistryV1】 | 
| `application/vnd.graphbinary-v1.0` | GraphBinaryMessageSerializerV1 |  | 
| `application/vnd.graphbinary-v1.0-stringd` | GraphBinaryMessageSerializerV1 | serializeResultToString: true | 
| `application/vnd.gremlin-v1.0+json` | GraphSONMessageSerializerGremlinV1 | ioRegistries：【org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerIoRegistryV1】 | 
| `application/vnd.gremlin-v2.0+json` | GraphSONMessageSerializerV2   (only works with WebSockets) | ioRegistries：【org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerIoRegistryV2】 | 
| `application/vnd.gremlin-v3.0+json` | `GraphSONMessageSerializerV3` |  | 
| `application/json` | GraphSONMessageSerializerV3 | ioRegistries：【org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerIoRegistryV3】 | 
| `application/vnd.graphbinary-v1.0` | GraphBinaryMessageSerializerV1 |  | 

**注意**  
 此處顯示的序列化程式資料表是指截至 TinkerPop 3.7.0 的命名。如果您想要進一步了解此變更，請參閱 [TinkerPop 升級文件](https://tinkerpop.apache.org/docs/current/upgrade/#_serializer_renaming)。Gryo 序列化支援已在 3.4.3 中棄用，並在 3.6.0 中正式移除。如果您明確使用 Gryo 或預設使用它的驅動程式版本，則應切換到 GraphBinary 或升級驅動程式。

## Lambda 步驟
<a name="feature-gremlin-differences-lambda"></a>

Neptune 不支援 Lambda 步驟。

## 不支援的 Gremlin 方法
<a name="feature-gremlin-differences-unsupported-methods"></a>

Neptune 不支援以下 Gremlin 方法：
+ `org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal.program(org.apache.tinkerpop.gremlin.process.computer.VertexProgram)`
+ `org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal.sideEffect(java.util.function.Consumer)`
+ `org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal.from(org.apache.tinkerpop.gremlin.structure.Vertex)`
+ `org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal.to(org.apache.tinkerpop.gremlin.structure.Vertex)`

例如，不允許以下周遊：`g.V().addE('something').from(__.V().next()).to(__.V().next())`。

**重要**  
這「只」******適用於以「文字字串」******傳送 Gremlin 查詢的方法。

## 不支援的 Gremlin 步驟
<a name="feature-gremlin-differences-unsupported-steps"></a>

Neptune 不支援以下 Gremlin 步驟：
+ Neptune 中僅部分支援 Gremlin [io( ) 步驟](http://tinkerpop.apache.org/docs/3.7.2/reference/#io-step)。它可以在讀取內容中使用，如 `g.io((url)).read()` 中所示，但不能寫入。

## Neptune 中的 Gremlin 圖形功能
<a name="gremlin-api-reference-features"></a>

Gremlin 的 Neptune 實作不會公開 `graph` 物件。下表列出 Grimlin 功能，並指出 Neptune 是否支持它們。

### Neptune 對 `graph` 功能的支援
<a name="gremlin-api-graph-features"></a>

Neptune 圖形功能 (如果支援) 與 `graph.features()` 命令將傳回的功能相同。


| 
| 
| 圖形功能 | 已啟用？ | 
| --- |--- |
| 交易 |  true | 
| ThreadedTransactions |  false | 
| Computer |  false | 
| Persistence |  true | 
| ConcurrentAccess |  true | 

### Neptune 對變數功能的支援
<a name="gremlin-api-variable-features"></a>


| 
| 
| 變數功能 | 已啟用？ | 
| --- |--- |
| Variables |  false | 
| SerializableValues |  false | 
| UniformListValues |  false | 
| BooleanArrayValues |  false | 
| DoubleArrayValues |  false | 
| IntegerArrayValues |  false | 
| StringArrayValues |  false | 
| BooleanValues |  false | 
| ByteValues |  false | 
| DoubleValues |  false | 
| FloatValues |  false | 
| IntegerValues |  false | 
| LongValues |  false | 
| MapValues |  false | 
| MixedListValues |  false | 
| StringValues |  false | 
| ByteArrayValues |  false | 
| FloatArrayValues |  false | 
| LongArrayValues |  false | 

### Neptune 對頂點功能的支援
<a name="gremlin-api-vertex-features"></a>


| 
| 
| 頂點功能 | 已啟用？ | 
| --- |--- |
| MetaProperties |  false | 
| DuplicateMultiProperties |  false | 
| AddVertices |  true | 
| RemoveVertices |  true | 
| MultiProperties |  true | 
| UserSuppliedIds |  true | 
| AddProperty |  true | 
| RemoveProperty |  true | 
| NumericIds |  false | 
| StringIds |  true | 
| UuidIds |  false | 
| CustomIds |  false | 
| AnyIds |  false | 

### Neptune 對頂點屬性功能的支援
<a name="gremlin-api-vertex-property-features"></a>


| 
| 
| 頂點屬性功能 | 已啟用？ | 
| --- |--- |
| UserSuppliedIds |  false | 
| AddProperty |  true | 
| RemoveProperty |  true | 
| NumericIds |  true | 
| StringIds |  true | 
| UuidIds |  false | 
| CustomIds |  false | 
| AnyIds |  false | 
| Properties |  true | 
| SerializableValues |  false | 
|  UniformListValues |  false | 
| BooleanArrayValues |  false | 
| DoubleArrayValues |  false | 
| IntegerArrayValues |  false | 
| StringArrayValues |  false | 
| BooleanValues |  true | 
| ByteValues |  true | 
| DoubleValues |  true | 
| FloatValues |  true | 
| IntegerValues |  true | 
| LongValues |  true | 
| MapValues |  false | 
| MixedListValues |  false | 
| StringValues |  true | 
| ByteArrayValues |  false | 
| FloatArrayValues |  false | 
| LongArrayValues |  false | 

### Neptune 對邊緣功能的支援
<a name="gremlin-api-edge-features"></a>


| 
| 
| 邊緣功能 | 已啟用？ | 
| --- |--- |
| AddEdges |  true | 
| RemoveEdges |  true | 
| UserSuppliedIds |  true | 
| AddProperty |  true | 
| RemoveProperty |  true | 
| NumericIds |  false | 
| StringIds |  true | 
| UuidIds |  false | 
| CustomIds |  false | 
| AnyIds |  false | 

### Neptune 對邊緣屬性功能的支援
<a name="gremlin-api-edge-property-features"></a>


| 
| 
| 邊緣屬性功能 | 已啟用？ | 
| --- |--- |
| Properties |  true | 
| SerializableValues |  false | 
| UniformListValues |  false | 
| BooleanArrayValues |  false | 
| DoubleArrayValues |  false | 
| IntegerArrayValues |  false | 
| StringArrayValues |  false | 
| BooleanValues |  true | 
| ByteValues |  true | 
| DoubleValues |  true | 
| FloatValues |  true | 
| IntegerValues |  true | 
| LongValues |  true | 
| MapValues |  false | 
| MixedListValues |  false | 
| StringValues |  true | 
| ByteArrayValues |  false | 
| FloatArrayValues |  false | 
| LongArrayValues |  false | 

# Amazon Neptune 中的 SPARQL 標準合規
<a name="feature-sparql-compliance"></a>

在列出適用的 SPARQL 標準之後，以下各節提供有關 Neptune 的 SPARQL 實作如何擴展或從這些標準分出來的特定詳細資料。

**Topics**
+ [SPARQL 的適用標準](#feature-sparql-applicable-standards)
+ [Neptune SPARQL 中的預設命名空間字首](#sparql-default-prefixes)
+ [SPARQL 預設圖形和具名圖形](#sparql-default-graph)
+ [Neptune 支援的 SPARQL XPath 建構子函數](#access-graph-sparql-xpath-constructors)
+ [查詢和更新的預設基礎 IRI](#opencypher-compliance-default-iri)
+ [Neptune 中的 xsd:dateTime 值](#access-graph-sparql-xsd-date-time)
+ [特殊浮點值的 Neptune 處理](#feature-overview-special-values-comparisons)
+ [Neptune 任意長度值的限制](#feature-overview-arbitrary-length-values)
+ [Neptune 擴充 SPARQL 中的等於比較](#feature-overview-sparql-not-equal)
+ [處理 Neptune SPARQL 中超出範圍的常值](#feature-overview-sparql-out-of-range)

Amazon Neptune 在實作 SPARQL 圖形查詢語言時符合下列標準。

## SPARQL 的適用標準
<a name="feature-sparql-applicable-standards"></a>
+ SPARQL 是依 2013 年 3 月 21 日的 W3C [SPARQL 1.1 查詢語言](https://www.w3.org/TR/sparql11-query/)建議定義。
+ SPARQL 更新協定和查詢語言是依 W3C [SPARQL 1.1 更新](https://www.w3.org/TR/sparql11-update/)規格定義。
+ 對於數值格式，SPARQL 遵循 [W3C XML 結構描述定義語言 (XSD) 1.1 第 2 部分：Datatypes](https://www.w3.org/TR/xmlschema11-2/) 規格，其與 IEEE 754 規格一致 ([IEEE 754-2019 - 浮點數運算的 IEEE 標準](https://standards.ieee.org/content/ieee-standards/en/standard/754-2019.html)；如需詳細資訊，另請參閱 [Wikipedia IEEE 754 頁面](https://en.wikipedia.org/wiki/IEEE_754))。不過，此規格不包含於 `IEEE 754-1985` 版本後引入的功能。

## Neptune SPARQL 中的預設命名空間字首
<a name="sparql-default-prefixes"></a>

Neptune 定義下列 SPARQL 查詢預設使用的字首。如需詳細資訊，請參閱 SPARQL 規格中的 [Prefixed Names](https://www.w3.org/TR/sparql11-query/#prefNames)。
+ `rdf`  – `http://www.w3.org/1999/02/22-rdf-syntax-ns#`
+ `rdfs` – `http://www.w3.org/2000/01/rdf-schema#`
+ `owl`  – `http://www.w3.org/2002/07/owl#`
+ `xsd`  – `http://www.w3.org/2001/XMLSchema#`

## SPARQL 預設圖形和具名圖形
<a name="sparql-default-graph"></a>

Amazon Neptune 會將每個三元組與一個具名圖形建立關聯。預設圖形是定義成所有具名圖形的聯集。

**查詢的預設圖形**  
若您提交 SPARQL 查詢而未透過 `GRAPH` 關鍵字或 `FROM NAMED` 之類的建構式明確指定圖形，Neptune 一律會考慮資料庫執行個體中的所有三元組。例如，以下查詢將從 Neptune SPARQL 端點傳回所有三元組：

`SELECT * WHERE { ?s ?p ?o }`

顯現於多個圖形中的三元組將僅傳回一次。

如需預設圖形規格的相關資訊，請參閱 SPARQL 1.1 查詢語言規格的 [RDF 資料集](https://www.w3.org/TR/sparql11-query/#rdfDataset)一節。

**指定具名圖形以進行載入、插入或更新**  
如果您在載入、插入或更新三元組時未指定具名圖形，Neptune 會使用由 URI `http://aws.amazon.com/neptune/vocab/v01/DefaultNamedGraph` 定義的備用具名圖形。

當您使用三元組類型的格式發出 Neptune `Load` 請求時，可使用 `parserConfiguration: namedGraphUri` 參數指定具名圖形以用於所有三元組。如需 `Load` 命令語法的相關資訊，請參閱 [Neptune 載入器命令](load-api-reference-load.md)。

**重要**  
 若您既沒有使用此參數也未指定具名圖形，則將使用備用 URI：`http://aws.amazon.com/neptune/vocab/v01/DefaultNamedGraph`。

如果透過 `SPARQL UPDATE` 載入三元組而未明確提供具名圖形目標，則亦將使用上述的備用具名圖形。

您可以使用四元組格式的 N-Quads，為資料庫中的每個三元組指定具名圖形。

**注意**  
使用 N-Quads 允許您將具名圖形留空不填。在此情況下即會使用 `http://aws.amazon.com/neptune/vocab/v01/DefaultNamedGraph`。  
您可以使用 `namedGraphUri` 剖析器組態選項，覆寫 N-Quads 的預設具名圖形。

## Neptune 支援的 SPARQL XPath 建構子函數
<a name="access-graph-sparql-xpath-constructors"></a>

SPARQL 標準允許 SPARQL 引擎支援一組可擴展的 XPath 建構子函數。Neptune 目前支援以下建構子函數，其中 `xsd` 字首定義為 `http://www.w3.org/2001/XMLSchema#`：
+ `xsd:boolean`
+ `xsd:integer`
+ `xsd:double`
+ `xsd:float`
+ `xsd:decimal`
+ `xsd:long`
+ `xsd:unsignedLong`

## 查詢和更新的預設基礎 IRI
<a name="opencypher-compliance-default-iri"></a>

因為 Neptune 叢集具有數個不同的端點，所以在解析相對 IRI 時，使用查詢或更新的請求 URL 做為基礎 IRI 可能會產生非預期的結果。

從[引擎 1.2.1.0 版](engine-releases-1.2.1.0.md)開始，如果明確的基礎 IRI 不是請求的一部分，Neptune 會使用 `http://aws.amazon.com/neptune/default/` 做為基礎 IRI。

在以下請求中，基礎 IRI 是請求的一部分：

```
BASE <http://example.org/default/>
INSERT DATA { <node1> <id> "n1" }

BASE <http://example.org/default/>
SELECT * { <node1> ?p ?o }
```

結果將是：

```
?p                                                   ?o
http://example.org/default/id                        n1
```

不過，在此請求中，不包括基礎 IRI：

```
INSERT DATA { <node1> <id> "n1" }

SELECT * { <node1> ?p ?o }
```

在此情況下，結果將是：

```
?p                                                   ?o
http://aws.amazon.com/neptune/default/id             n1
```

## Neptune 中的 xsd:dateTime 值
<a name="access-graph-sparql-xsd-date-time"></a>

基於效能考量，Neptune 一律會將日期/時間值儲存為國際標準時間 (UTC)。這能讓直接比較很有效率。

這也表示如果您輸入指定特定時區的 `dateTime` 值，Neptune 就會將值轉換為 UTC 並捨棄該時區資訊。接下來，當您收到 `dateTime` 後，該執會以 UTC 呈現而非原始時區的時間，而且您也無法再判斷原始時區。

## 特殊浮點值的 Neptune 處理
<a name="feature-overview-special-values-comparisons"></a>

Neptune 處理 SPARQL 特殊浮點值的方式如下。

### Neptune 中的 SPARQL NaN 處理
<a name="feature-overview-NaN-comparisons"></a>

在 Neptune 中，SPARQL 可以接受查詢中的 `NaN` 值。signalling 和 quiet `NaN` 值之間沒有任何區別。Neptune 會將所有 `NaN` 值視為 quiet。

在語意上，不可能進行 `NaN` 的比較，因為沒有任何值大於、小於或等於 `NaN`。這表示理論上，比較一端的 `NaN` 值和另一端的「任何內容」**永遠不相符。

 不過，[XSD 規格](https://www.w3.org/TR/xmlschema-2/#double)確實將兩個 `xsd:double` 或 `xsd:float` `NaN` 值視為相等。對於 `IN` 篩選條件、篩選條件表達式的等於運算子，以及完全相符語義 (在三重模式的物件位置中具有 `NaN`)，Neptune 皆遵循此原則。

### Neptune 中的 SPARQL 無限值處理
<a name="feature-overview-infinity-comparisons"></a>

在 Neptune 中，SPARQL 可接受查詢中的 `INF` 或 `-INF` 值。`INF` 會相比為大於任何其他數值，而 `-INF` 會相比為小於任何其他數值。

比較具有相符符號的兩個 INF 值時，無論其類型如何皆彼此相等 (例如，float `-INF` 等於 double `-INF`)。

當然，因為沒有任何值大於、小於或等於 `NaN`，所以不可能和 `NaN` 比較。

### Neptune 中的 SPARQL 負零處理
<a name="feature-overview-zero-comparisons"></a>

Neptune 會將負零值標準化為不帶正負號的零。負零值可用於查詢中，但不會原樣記錄在資料庫中，而且不等於不帶正負號的零。

## Neptune 任意長度值的限制
<a name="feature-overview-arbitrary-length-values"></a>

Neptune 將 SPARQL 中的 XSD 整數、浮點數和小數值的儲存大小限制在 64 位元。使用較大的值會導致 `InvalidNumericDataException` 錯誤。

## Neptune 擴充 SPARQL 中的等於比較
<a name="feature-overview-sparql-not-equal"></a>

SPARQL 標準為值運算式定義了三元邏輯，其中，值運算式可評估為 `true`、`false` 或 `error`。[SPARQL 1.1 規格](https://www.w3.org/TR/sparql11-query/#func-RDFterm-equal)中定義的術語相等性的預設語義適用於 `FILTER` 條件中的 `=` 與 `!=` 比較，這會在比較規格中[運算子資料表](https://www.w3.org/TR/sparql11-query/#OperatorMapping)中未明確比較的資料類型時產生一個 `error`。

這種行為可能會導致不直觀的結果，如下列範例所示。

資料：

```
<http://example.com/Server/1> <http://example.com/ip> "127.0.0.1"^^<http://example.com/datatype/IPAddress>
```

查詢 1：

```
SELECT * WHERE {
    <http://example.com/Server/1> <http://example.com/ip> ?o .
    FILTER(?o = "127.0.0.2"^^<http://example.com/datatype/IPAddress>)
}
```

查詢 2：

```
SELECT * WHERE {
    <http://example.com/Server/1> <http://example.com/ip> ?o .
    FILTER(?o != "127.0.0.2"^^<http://example.com/datatype/IPAddress>)
}
```

透過 Neptune 在 1.0.2.1 版本以前所使用的預設 SPARQL 語義，這兩個查詢都會傳回空結果。原因是 `?o = "127.0.0.2"^^<http://example.com/IPAddress>` 在評估 `?o := "127.0.0.1"^^<http://example.com/IPAddress>` 時會產生 `error`，而不是 `false`，因為沒有為自訂資料類型 `<http://example.com/IPAddress>` 指定明確的比較規則。因此，第二個查詢中的否定版本也會產生 `error`。在這兩個查詢中，`error` 會導致篩選出候選解決方案。

從 1.0.2.1 版開始，Neptune 已根據規格擴展 SPARQL 不等式運算子。請參閱 [SPARQL 第 1.1 節，運算子可擴充性](https://www.w3.org/TR/sparql11-query/#operatorExtensibility)，讓引擎定義如何跨使用者定義和不可比較內建資料類型進行比較的其他相關規則。

使用此選項，如果常值和資料類型在語法上相等，則 Neptune 會立即將在運算子對應表中未明確定義的任何兩個資料類型的比較視同評估為 `true`，否則為 false。任何情況下都不會發生 `error`。

使用這些新的語意，第二個查詢就會傳回 `"127.0.0.1"^^<http://example.com/IPAddress>`，而不是空的結果。

## 處理 Neptune SPARQL 中超出範圍的常值
<a name="feature-overview-sparql-out-of-range"></a>

XSD 語義會定義每個數值類型的值空間，但 `integer` 和 `decimal` 除外。這些定義會將每種類型限制在某個範圍的值內。例如，範圍 `xsd:byte` 的範圍為 -128 到 \$1127 (頭尾皆含)。任何超出此範圍的值都視為無效。

如果您嘗試在某類型的值空間外指派常值 (例如，嘗試將 `xsd:byte` 設為 999 的常值)，Neptune 會接受此超出範圍值的原樣，但不會四捨五入或截斷。但因為指定的類型不能代表此值，所以不會保存為數值。

也就是說，即使 `"999"^^xsd:byte` 是已定義之 `xsd:byte` 值範圍外的值，Neptune 也會接受它。但是，在資料庫中保存該值之後，此值只能用於三重模式物件位置的完全相符語義。因為超出範圍的常值不被視為數值，所以不會對其執行任何範圍篩選。

SPARQL 1.1 規格會以格式 `numeric`*-operator-*`numeric`、`string`*-operator-*`string`、`literal`*-operator-*`literal` 等等定義[範圍運算子](https://www.w3.org/TR/sparql11-query/#OperatorMapping)。Neptune 無法執行如 `invalid-literal`*-operator-*`numeric-value` 之類的範圍比較運算子。

# Amazon Neptune 中的 openCypher 規格合規
<a name="feature-opencypher-compliance"></a>

OpenCypher 的 Amazon Neptune 版本通常支援目前 OpenCypher 規格 (即 [Cypher 查詢語言參考第 9 版](https://s3.amazonaws.com/artifacts.opencypher.org/openCypher9.pdf)) 中定義的子句、運算子、運算式、函數和語法。下面列出了 Neptune 對 OpenCypher 支援的限制和差異。

 Amazon Neptune 也支援 openCypher 規格範圍以外的多種功能。請參閱 [Amazon Neptune 中的 openCypher 延伸模組](access-graph-opencypher-extensions.md) 以取得詳細資訊。

**注意**  
Cypher 的目前 Neo4j 實作包含了上述 OpenCypher 規格中未包含的功能。如果您要將目前 Cypher 程式碼遷移至 Neptune，請參閱 [Neptune 與 Neo4j 的相容性](migration-compatibility.md) 和 [重寫 Cypher 查詢以在 Neptune 上的 OpenCpher 中執行](migration-opencypher-rewrites.md) 以取得詳細資訊。

## Neptune 中對 openCypher 子句的支援
<a name="opencypher-compliance-clauses"></a>

Neptune 支援下列子句，除非另有說明：
+ `MATCH` – 支援，但目前不支援 *`shortestPath()`* 和 *`allShortestPaths()`*。
+ `OPTIONAL MATCH`
+ *`MANDATORY MATCH`* – 目前在 Neptune 中**不**支援。不過，Neptune 確實支援 `MATCH` 查詢中的[自訂 ID 值](access-graph-opencypher-extensions.md#opencypher-compliance-custom-ids)。
+ `RETURN` – 支援，但與 `SKIP` 或 `LIMIT` 的非靜態值搭配使用時除外。例如，目前下列項目無法運作：

  ```
  MATCH (n)
  RETURN n LIMIT toInteger(rand())    // Does NOT work!
  ```
+ `WITH` – 支援，但與 `SKIP` 或 `LIMIT` 的非靜態值搭配使用時除外。例如，目前下列項目無法運作：

  ```
  MATCH (n)
  WITH n SKIP toInteger(rand())
  WITH count() AS count
  RETURN count > 0 AS nonEmpty    // Does NOT work!
  ```
+ `UNWIND`
+ `WHERE`
+ `ORDER BY`
+ `SKIP`
+ `LIMIT`
+ `CREATE` – Neptune 可讓您在 `CREATE` 查詢中建立[自訂 ID 值](access-graph-opencypher-extensions.md#opencypher-compliance-custom-ids)。
+ `DELETE`
+ `SET`
+ `REMOVE`
+ `MERGE` – Neptune 支援 `MERGE` 查詢中的[自訂 ID 值](access-graph-opencypher-extensions.md#opencypher-compliance-custom-ids)。
+ *`CALL[YIELD...]`* – 目前在 Neptune 中**不**支援。
+ `UNION, UNION ALL` – 支援唯讀查詢，但目前**不**支援變動查詢。
+  `USING`   –   `USING` 支援引擎 [1.3.2.0 版。](https://docs.aws.amazon.com//neptune/latest/userguide/engine-releases-1.3.2.0.html)如需詳細資訊[，請參閱查詢提示](https://docs.aws.amazon.com//neptune/latest/userguide/opencypher-query-hints.html)。

## Neptune 中對 openCypher 運算子的支援
<a name="opencypher-compliance-operators"></a>

Neptune 支援下列運算子，除非另有說明：

**一般運算子**
+ `DISTINCT`
+ 用於存取巢狀常值映射屬性的 `.` 運算子。

**數學運算子**
+ `+` 加法運算子。
+ `-` 減法運算子。
+ `*` 乘法運算子。
+ `/` 除法運算子。
+ `%` 模數除法運算子。
+ `^` 指數運算子*未受支援*。

**比較運算子**
+ `=` 加法運算子。
+ `<>` 不等式運算子。
+ 支援 `<` 小於運算子，但其中一個引數是 Path、List 或 Map 除外。
+ 支援 `>` 大於運算子，但其中一個引數是 Path、List 或 Map 除外。
+ 支援 `<=` 小於或大於運算子，但其中一個引數是 Path、List 或 Map 除外。
+ 支援 `>=` 大於或等於運算子，但其中一個引數是 Path、List 或 Map 除外。
+ `IS NULL`
+ `IS NOT NULL`
+ 如果要搜尋的資料是字串，則支援 `STARTS WITH`。
+ 如果要搜尋的資料是字串，則支援 `ENDS WITH`。
+ 如果要搜尋的資料是字串，則支援 `CONTAINS`。

**布林值運算子**
+ `AND`
+ `OR`
+ `XOR`
+ `NOT`

**字串運算子**
+ `+` 串連運算子。

**清單運算子**
+ `+` 串連運算子。
+ `IN` (檢查清單中是否存在項目)

## Neptune 中對 openCypher 運算式的支援
<a name="opencypher-compliance-expressions"></a>

Neptune 支援下列運算式，除非另有說明：
+ `CASE`
+ Neptune 中目前**不**支援 `[]` 運算式，用於存取節點、關係或映射內動態計算的屬性索引鍵。例如，下列項目無法運作：

  ```
  MATCH (n)
  WITH [5, n, {key: 'value'}] AS list
  RETURN list[1].name
  ```

## Neptune 中對 openCypher 函數的支援
<a name="opencypher-compliance-functions"></a>

Neptune 支援下列函數，除非另有說明：

**述詞函數**
+ `exists()`

**純量函數**
+ `coalesce()`
+ `endNode()`
+ `epochmillis()`
+ `head()`
+ `id()`
+ `last()`
+ `length()`
+ `randomUUID()`
+ `properties()`
+ `removeKeyFromMap`
+ `size()` – 此過載方法目前僅適用於模式運算式、清單和字串
+ `startNode()`
+ `timestamp()`
+ `toBoolean()`
+ `toFloat()`
+ `toInteger()`
+ `type()`

**彙總函數**
+ `avg()`
+ `collect()`
+ `count()`
+ `max()`
+ `min()`
+ `percentileDisc()`
+ `stDev()`
+ `percentileCont()`
+ `stDevP()`
+ `sum()`

**列出函數**
+ [`join()`](access-graph-opencypher-extensions.md#opencypher-compliance-join-function) (將清單中的字串串連為單一字串)
+ `keys()`
+ `labels()`
+ `nodes()`
+ `range()`
+ `relationships()`
+ `reverse()`
+ `tail()`

**數學函數 – 數字**
+ `abs()`
+ `ceil()`
+ `floor()`
+ `rand()`
+ `round()`
+ `sign()`

**數學函數 – 對數**
+ `e()`
+ `exp()`
+ `log()`
+ `log10()`
+ `sqrt()`

**數學函數 – 三角函數**
+ `acos()`
+ `asin()`
+ `atan()`
+ `atan2()`
+ `cos()`
+ `cot()`
+ `degrees()`
+ `pi()`
+ `radians()`
+ `sin()`
+ `tan()`

**字串函數**
+ [`join()`](access-graph-opencypher-extensions.md#opencypher-compliance-join-function) (將清單中的字串串連為單一字串)
+ `left()`
+ `lTrim()`
+ `replace()`
+ `reverse()`
+ `right()`
+ `rTrim()`
+ `split()`
+ `substring()`
+ `toLower()`
+ `toString()`
+ `toUpper()`
+ `trim()`

**使用者定義的函數**

Neptune 中目前**不**支援*使用者定義的函數*。

## Neptune 特定的 openCypher 實作詳細資訊
<a name="opencypher-compliance-differences"></a>

以下各節描述了其中 OpenCypher 的 Neptune 實作可能不同於或超出 [OpenCypher 規格](https://s3.amazonaws.com/artifacts.opencypher.org/openCypher9.pdf)的方式。

### Neptune 中的可變長度路徑（VLP）評估
<a name="opencypher-compliance-differences-vlp"></a>

可變長度路徑 (`VLP`) 評估會探索圖形中節點之間的路徑。路徑長度可在查詢中不受限制。為了防止循環，[OpenCypher 規格](https://s3.amazonaws.com/artifacts.opencypher.org/openCypher9.pdf)指定每個解決方案必須周遊每個邊緣最多一次。

對於 VLP，Neptune 實作會偏離 OpenCypher 規格，因為它只支援屬性等式篩選條件的常數值。採取下列查詢：

```
MATCH (x)-[:route*1..2 {dist:33, code:x.name}]->(y) return x,y
```

因為 `x.name` 屬性等式篩選條件值不是常數，所以此查詢會產生 `UnsupportedOperationException` 並顯示訊息：`Property predicate over variable-length relationships with non-constant expression is not supported in this release.`

### Neptune openCypher 實作中的暫時支援 (Neptune 資料庫 1.3.1.0 及更新版本）
<a name="opencypher-compliance-time"></a>

Neptune 目前為 OpenCypher 中的時間函數提供了有限的支援。它支援時間類型的 `DateTime` 資料類型。

`datetime()` 函數可以用來取得目前 UTC 日期和時間，如下所示：

```
RETURN  datetime() as res
```

日期和時間值可從 `"`*date*`T`*time*`"` 格式的字串中剖析而來，其中 *date* 和 *time* 皆以下面的其中一種支援形式表示：

**支援的日期格式**
+ `yyyy-MM-dd`
+ `yyyyMMdd`
+ `yyyy-MM`
+ `yyyy-DDD`
+ `yyyyDDD`
+ `yyyy`

**支援的時間格式**
+ `HH:mm:ssZ`
+ `HHmmssZ`
+ `HH:mm:ssZ`
+ `HH:mmZ`
+ `HHmmZ`
+ `HHZ`
+ `HHmmss`
+ `HH:mm:ss`
+ `HH:mm`
+ `HHmm`
+ `HH`

例如：

```
RETURN datetime('2022-01-01T00:01')      // or another example:
RETURN datetime('2022T0001')
```

請注意，Neptune OpenCypher 中的所有日期/時間值都以 UTC 值的形式儲存和擷取。

Neptune OpenCypher 使用 `statement` 時鐘，這表示在整個查詢期間使用相同的時刻。同一交易中的不同查詢可能會使用不同的時刻。

Neptune 不支援在呼叫 `datetime()` 時使用函數 。例如，下列項目無法運作：

```
CREATE (:n {date:datetime(tostring(2021))})  // ---> NOT ALLOWED!
```

Neptune 確實支援將 `datetime` 轉換為 `epochmillis` 的 `epochmillis()` 函數。例如：

```
MATCH (n) RETURN epochMillis(n.someDateTime)
1698972364782
```

Neptune 目前不支援 `DateTime` 物件上的其他函數和操作，例如加法和減法。

### Neptune openCypher 實作的暫時支援 (Neptune Analytics 和 Neptune 資料庫 1.3.2.0 及更高版本）
<a name="opencypher-compliance-time-na"></a>

下列 OpenCypher 的日期時間功能適用於 Neptune Analytics。或者，您可以使用 實驗室模式參數`DatetimeMillisecond=enabled`，在 Neptune 引擎版本 1.3.2.0 及更高版本上啟用下列日期時間功能。如需在 實驗室模式中使用此功能的詳細資訊，請參閱 [延長日期時間支援](features-lab-mode.md#labmode-extended-datetime-support)。
+ 支援毫秒。日期時間常值一律會以毫秒傳回，即使毫秒為 0。（先前的行為是截斷毫秒。)

  ```
  CREATE (:event {time: datetime('2024-04-01T23:59:59Z')})
  
  # Returning the date returns with 000 suffixed representing milliseconds
  MATCH(n:event)
  RETURN n.time as datetime
  
  {
    "results" : [ {
      "n" : {
        "~id" : "0fe88f7f-a9d9-470a-bbf2-fd6dd5bf1a7d",
        "~entityType" : "node",
        "~labels" : [ "event" ],
        "~properties" : {
          "time" : "2024-04-01T23:59:59.000Z"
        }
      }
    } ]
  }
  ```
+ 支援透過儲存的屬性或中繼結果呼叫 datetime() 函數。例如，在此功能之前，以下查詢是不可能的。

  透過屬性的日期時間 ()：

  ```
  // Create node with property 'time' stored as string
  CREATE (:event {time: '2024-04-01T23:59:59Z'})
  
  // Match and return this property as datetime
  MATCH(n:event)
  RETURN datetime(n.time) as datetime
  ```

  中繼結果的日期時間 ()：

  ```
  // Parse datetime from parameter
  UNWIND $list as myDate
  RETURN datetime(myDate) as d
  ```
+ 現在也可以儲存在上述情況下建立 的日期時間權限。

  將日期時間從一個屬性的字串屬性儲存至另一個屬性：

  ```
  // Create node with property 'time' stored as string
  CREATE (:event {time: '2024-04-01T23:59:59Z', name: 'crash'})
  
  // Match and update the same property to datetime type
  MATCH(n:event {name: 'crash'})
  SET n.time = datetime(n.time)
  
  // Match and update another node's property
  MATCH(e:event {name: 'crash'})
  MATCH(n:server {name: e.servername})
  SET n.time = datetime(e.time)
  ```

  使用 datetime 屬性從 參數批次建立節點：

  ```
  // Batch create from parameter
  UNWIND $list as events
  CREATE (n:crash) {time: datetime(events.time)}
  // Parameter value
  {
    "x":[
      {"time":"2024-01-01T23:59:29", "name":"crash1"},
      {"time":"2023-01-01T00:00:00Z", "name":"crash2"}
    ]
  }
  ```
+ 支援較大的 ISO8601 日期時間格式子集。請參閱以下 。

支援的格式

 日期時間值的格式為 【Date】T【Time】【Timezone】，其中 T 是分隔符號。如果未提供明確的時區，則會假設 UTC (Z) 為預設值。

時區

支援的時區格式為：
+ \$1/-HH：mm
+ \$1/-HHmm
+ \$1/-HH

 日期時間字串中存在時區是選用的。如果時區位移為 0，則可以使用 Z 而不是上面的時區後綴來表示 UTC 時間。時區的支援範圍是 -14：00 到 \$114：00。

Date

如果沒有時區，或時區為 UTC (Z)，則支援的日期格式如下：

**注意**  
DDD 是指序日期，代表一年中從 001 到 365 （閏年為 366) 的一天。例如，2024-002 代表 2024 年 1 月 2 日。
+ `yyyy-MM-dd`
+ `yyyyMMdd`
+ `yyyy-MM`
+ `yyyyMM`
+ `yyyy-DDD`
+ `yyyyDDD`
+ `yyyy`

如果選擇 Z 以外的時區，支援的日期格式會限制如下：
+ `yyyy-MM-dd`
+ `yyyy-DDD`
+ `yyyyDDD`

日期的支援範圍是從 1400-01-01 到 9999-12-31。

時間

如果沒有時區，或時區為 UTC (Z)，則支援的時間格式為：
+ `HH:mm:ss.SSS`
+ `HH:mm:ss`
+ `HHmmss.SSS`
+ `HHmmss`
+ `HH:mm`
+ `HHmm`
+ `HH`

如果選擇 Z 以外的時區，則支援的時間格式僅限於下列項目：
+ `HH:mm:ss`
+ `HH:mm:ss.SSS`

### Neptune openCypher 語言語義中的差異
<a name="opencypher-compliance-semantics"></a>

Neptune 會將節點和關係 ID 表示為字串，而非整數。ID 等於透過資料載入器提供的 ID。如果資料欄有命名空間，則命名空間加上 ID。因此，`id` 函數會傳回字串而非整數。

`INTEGER` 資料類型限制為 64 位元。使用 `TOINTEGER` 函數將較大的浮點數值或字串值轉換為整數時，負值會截斷為 `LLONG_MIN`，而正值會截斷為 `LLONG_MAX`。

例如：

```
RETURN TOINTEGER(2^100)
>  9223372036854775807

RETURN TOINTEGER(-1 * 2^100)
>  -9223372036854775808
```

### 多值屬性
<a name="openCypher-compliance-mvp"></a>

 雖然 openCypher CREATE 不會建立多值屬性，但它們可以存在於使用 Gremlin (Neptune 資料庫） 建立的資料中，或在載入資料 (Neptune 資料庫和 Neptune Analytics) 時存在。如果 Neptune OpenCypher 遇到一個多值屬性，其中一個值是任意選擇的，這會建立一個非確定性的結果。

### NaN valuse 的處理
<a name="openCypher-compliance-handling-nan"></a>

 Neptune 對`NaN`屬性值比較的處理方式未定義。依賴這類比較可能會導致非預期或非確定性的結果。

# Neptune 圖形資料模型。
<a name="feature-overview-data-model"></a>

Amazon Neptune 圖形資料的基本單位是四個位置 (quad) 元素，類似資源描述架構 (RDF) quad。以下是 Neptune quad 的四個位置：
+ `subject    (S)`
+ `predicate  (P)`
+ `object     (O)`
+ `graph      (G)`

每個 quad 是一個陳述式，可做出關於一個或多個資源的宣告。陳述式可以宣告兩個資源之間的關係，或者將屬性 (鍵/值組) 連接到資源。您一般可以將 quad 述詞值視為陳述式的動詞。它會描述正在定義的關係或屬性的類型。物件是關係的目標，或是屬性的值。範例如下：
+ 可透過將來源頂點識別符存放在 `S` 位置中、將目標頂點識別符存放在 `O` 位置中，以及將邊緣標籤存放在 `P` 位置，來表示兩個頂點之間的關係。
+ 可透過將元素識別符存放在 `S` 位置中、將屬性索引鍵存放在 `P` 位置中，以及將屬性值存放在 `O` 位置中，來表示屬性。

圖形位置 `G` 在不同堆疊中的使用方式不同。對於 Neptune 中的 RDF 資料，`G` 位置包含[具名圖形識別符](https://www.w3.org/TR/rdf11-concepts/#section-dataset)。對於 Gremlin 中的屬性圖，它用於在邊緣的情況下存放邊緣 ID 值。在所有其他情況下，它會預設為固定的值。

具有共用資源識別符的一組 quad 陳述式可建立圖形。

# 使用者面向值的字典
<a name="feature-overview-storage-dictionary"></a>

Neptune 不會將大多數使用者面向值直接儲存在其維護的各種索引中。相反地，它會將它們個別儲存在字典中，並使用 8 位元組識別符在索引中取代它們。
+ 將進入 `S`、`P` 或 `G` 索引的所有使用者面向值都以這種方式儲存在字典中。
+ 在 `O` 索引中，數值會直接儲存在索引中 (內嵌)。這包括 `date` 和 `datetime` 值 (以 Epoch 中的毫秒表示)。
+ 將進入 `O` 索引的所有其他使用者面向值都會儲存在字典中，並在索引中以 ID 表示。

字典包含使用者面向值與 `value_to_id` 索引中 8 位元組 ID 的正向映射。

它會將 8 位元組 ID 與值的反向映射儲存在兩個索引之一，取決於值的大小：
+ `id_to_value` 索引會將 ID 映射至內部編碼後小於 767 個位元組的使用者面向值。
+ `id_to_blob` 索引會將 ID 映射至較大的使用者面向值。

# 陳述式在 Neptune 中如何編製索引
<a name="feature-overview-storage-indexing"></a>

當您查詢 quad 圖表，您可以對每個 quad 指定值限制，也可以不指定。查詢會傳回符合您指定之值限制的所有 quad。

 Neptune 使用索引來解析圖形查詢模式。這些索引位於圖形邊緣的四個主要元件上：主體 (LPG 中的來源頂點）、述詞 (RDF) 或屬性或邊緣標籤 (LPG)、物件 (LPG 中的目標頂點或屬性值），以及圖形 (RDF) 或邊緣識別符 (LPG)。這四個四元元件位置有 16 (2^4) 個可能的存取模式。您可以有效率地查詢所有 16 種模式，而不必使用六個索引進行掃描和篩選。每個 quad 陳述式索引使用由以不同順序串連的四個位置值組成的索引鍵。涵蓋所有 16 個存取路徑的 quad 陳述式索引可能組合為：

```
       Access Pattern                                     Index key order
  ----------------------------------------------------    ---------------
   1.  ????  (No constraints; returns every quad)             SPOG
   2.  SPOG  (Every position is constrained)                  SPOG
   3.  SPO?  (S, P, and O are constrained; G is not)          SPOG
   4.  SP??  (S and P are constrained; O and G are not)       SPOG
   5.  S???  (S is constrained; P, O, and G are not)          SPOG
   6.  S??G  (S and G are constrained; P and O are not)       SPOG

   7.  ?POG  (P, O, and G are constrained; S is not)          POGS
   8.  ?PO?  (P and O are constrained; S and G are not)       POGS
   9.  ?P??  (P is constrained; S, O, and G are not)          POGS

  10.  ?P?G  (P and G are constrained; S and O are not)       GPSO
  11.  SP?G  (S, P, and G are constrained; O is not)          GPSO
  12.  ???G  (G is constrained; S, P, and O are not)          GPSO

  13.  S?OG  (S, O, and G are constrained; P is not)          OGSP
  14.  ??OG  (O and G are constrained; S and P are not)       OGSP
  15.  ??O?  (O is constrained; S, P, and G are not)          OGSP

  16.  S?O?  (S and O are constrained; P and G are not)       OSGP
```

根據預設，Neptune 只會建立和維護這六個索引中的三個：
+ `SPOG –  ` 使用 `Subject + Predicate + Object + Graph` 組成的索引鍵。
+ `POGS –  ` 使用 `Predicate + Object + Graph + Subject` 組成的索引鍵。
+ `GPSO –  ` 使用 `Graph + Predicate + Subject + Object` 組成的索引鍵。

這三個索引會處理許多最常見的存取模式。只維護三個完整陳述式索引 (而非六個)，可大幅減少支援不經掃描和篩選而快速存取所需的資源。例如，每當頂點或頂點和屬性識別符等位置字首繫結時，`SPOG` 索引會允許有效查詢。只有存放於 `P` 位置的邊緣或屬性標籤繫結時，`POGS` 索引才會允許有效存取。

尋找陳述式的低層級 API 採用的陳述式模式，其中有些位置已知，而其餘則保留供索引搜尋探索。透過根據其中一個陳述式索引的索引鍵順序，在索引鍵字首索引鍵中構成已知位置，Neptune 執行範圍掃描來擷取符合已知位置的所有陳述式。

不過，根據預設，Neptune 未**建立的其中一個陳述式索引是反向周遊 `OSGP` 索引，它可以跨物件和主題收集述詞。Neptune 預設會改為在個別索引中追蹤它用來進行 `{all P x POGS}` 聯合掃描的不同述詞。使用 Gremlin 時，述詞對應到屬性或邊緣標籤。

如果圖形中的不同述詞量很大時，預設的 Neptune 存取策略會變得沒有效率。例如，在 Gremlin 中，未指定邊緣標籤的 `in()` 步驟，或內部使用 `in()` 的任何步驟 (例如 `both()` 或 `drop()`) 可能會變得沒有效率。

## 使用實驗室模式啟用 OSGP 索引建立
<a name="feature-overview-storage-indexing-osgp"></a>

如果您的資料模型建立大量不同的述詞，可能會遇到效能降低和營運成本增加的情況，這些可藉由使用實驗室模式來啟用 [OSGP 索引](features-lab-mode.md#features-lab-mode-features-osgp-index) (除了 Neptune 根據預設維護的三個索引以外) 而大幅改善。

啟用 OSGP 索引可能會有幾個缺點：
+ 插入速率最多可能減慢 23%。
+ 儲存量增加高達 20%。
+ 均等觸及所有索引的讀取查詢 (這是很少見的情況) 可能會增加延遲。

不過，一般而言，啟用具有大量不同述詞之資料庫叢集的 OSGP 索引是值得的。物件型搜尋變成很有效率 (例如，尋找頂點的所有傳入邊緣，或連線到給定物件的所有主體)，因此，降低頂點也變得更有效率。

**重要**  
在載入任何資料之前，您只能在空白的資料庫叢集中啟用 OSGP 索引。

   

## Neptune 資料模型中的 Gremlin 陳述式
<a name="feature-overview-storage-indexing-gremlin"></a>

Gremlin 屬性圖資料在 SPOG 模型中使用三類陳述式來表示，即：
+ [頂點標籤陳述式](gremlin-explain-background-statements.md#gremlin-explain-background-vertex-labels)
+ [邊緣陳述式](gremlin-explain-background-statements.md#gremlin-explain-background-edge-statements) 
+ [屬性陳述式](gremlin-explain-background-statements.md#gremlin-explain-background-property-statements) 

如需如何在 Gemlin 查詢中使用這些陳述式的說明，請參閱 [了解 Gremlin 查詢如何在 Neptune 中運作](gremlin-explain-background.md)。

# Neptune 查詢快取可加速讀取查詢
<a name="feature-overview-lookup-cache"></a>

Amazon Neptune 會實作查詢快取，其可使用 `R5d` 執行個體的 NVMe 型 SSD，針對經常重複查詢屬性值或 RDF 常值的查詢改善讀取效能。查詢快取會暫時將這些值儲存在 NVMe SSD 磁碟區中，在這裡可以快速存取它們。

如果需要從叢集儲存磁碟區而非記憶體擷取屬性值或常值，則傳回大量頂點和邊緣或許多 RDF 三元組之屬性的讀取查詢可能會有較高的延遲。範例包括長時間執行的讀取查詢，這些查詢會從身分圖傳回大量完整名稱，或從詐騙偵測圖傳回 IP 地址。隨著查詢傳回的屬性值或 RDF 常值數量增加，可用記憶體會減少，而且您的查詢執行效能可能會大幅降低。

# Neptune 查詢快取的使用案例
<a name="feature-overview-lookup-cache-when-to-use"></a>

查詢快取僅在您的讀取查詢傳回非常大量頂點和邊緣或 RDF 三元組的屬性時才有幫助。

為了最佳化查詢效能，Amazon Neptune 會使用 `R5d` 執行個體類型，為這類屬性值或常值建立大型快取。然後，從快取擷取它們會比從叢集儲存磁碟區擷取它們快得多。

根據經驗法則，只有在滿足下列三個條件的情況下，才能啟用查詢快取：
+ 您一直觀察到讀取查詢中的延遲增加。
+ 您還觀察到 `BufferCacheHitRatio` [CloudWatch 指標](cw-metrics.md#cw-metrics-available)在執行讀取查詢時下降 (請參閱 [使用 Amazon CloudWatch 監控 Neptune](cloudwatch.md))。
+ 在呈現結果之前，您的讀取查詢會花費大量時間實體化傳回值 (請參閱下面的 Gremlin-profile 範例，取得確定要針對一個查詢具體化多少屬性值的方法)。

**注意**  
此功能「僅」**在上述特定案例中有幫助。例如，查詢快取根本無法幫助彙總查詢。除非您正在執行將從查詢快取得益的查詢，否則沒有理由使用 `R5d` 執行個體類型，而非同等且費用較低的 `R5` 執行個體類型。

如果您使用的是 Gremlin，您可以使用 [Gremlin `profile` API](gremlin-profile-api.md) 評估查詢的具體化成本。在「索引操作」下，它會顯示執行期間具體化的術語數量：

```
Index Operations
Query execution:
    # of statement index ops: 3
    # of unique statement index ops: 3
    Duplication ratio: 1.0
    # of terms materialized: 5273
Serialization:
    # of statement index ops: 200
    # of unique statement index ops: 140
    Duplication ratio: 1.43
    # of terms materialized: 32693
```

具體化的非數字術語數量直接與 Neptune 必須執行的術語查詢數量成正比。

# 使用查詢快取
<a name="feature-overview-lookup-cache-using"></a>

查詢快取僅適用於 `R5d` 執行個體類型，預設會自動將其啟用。Neptune `R5d` 執行個體具有與 `R5` 執行個體相同的規格，加上高達 1.8 TB 的本機 NVMe 型 SSD 儲存體。查詢快取是執行個體特定的，且受益的工作負載可以專門導向至 Neptune 叢集中的 `R5d` 執行個體，而其他工作負載則可以導向至 `R5` 或其他執行個體類型。

若要在 Neptune 執行個體上使用查詢快取，只要將該執行個體升級至 `R5d` 執行個體類型即可。當您這麼做時，Neptune 會自動將資料庫叢集參數設定為 [neptune\$1lookup\$1cache](parameters.md#parameters-db-cluster-parameters-neptune_lookup_cache) `1`（已啟用），並在該特定執行個體上建立查詢快取。然後，您可以使用 [執行個體狀態](access-graph-status.md) API 來確認快取已啟用。

同樣地，若要在給定執行個體上停用查詢快取，請將執行個體從 `R5d` 執行個體類型縮減至相等的 `R5` 執行個體類型。

啟動 `R5d` 執行個體時，會啟用查詢快取且其處於冷啟動模式中，表示它是空白的。處理查詢時，Neptune 首先會在查詢快取中檢查是否有屬性值或 RDF 常值，並新增它們 (如果尚未存在的話)。這會逐漸預熱快取。

當您將需要屬性值或 RDF 常值查詢的讀取查詢導向至 R5d「讀取器」**執行個體時，讀取效能會在其快取預熱時稍微降低。不過，當快取預熱時，讀取效能會大幅加快，而且您也可能會看到與命中快取而非叢集儲存體的查詢相關的 I/O 成本下降。記憶體使用率也會改善。

如果您的「寫入器」**執行個體是 `R5d`，則它會在每次寫入操作時自動預熱其查詢快取。此方法確實會稍微增加寫入查詢的延遲，但會更有效率地預熱查詢快取。然後，如果將需要屬性值或 RDF 常值查詢的讀取查詢導向至寫入器執行個體，則您會立即開始獲得改善的讀取效能，因為已在該處快取這些值。

此外，如果您在 `R5d` 寫入器執行個體上執行大量載入器，則可能會注意到其效能由於快取而略為降低。

因為查詢快取是每個節點特定的，所以主機更換會將快取重設為冷啟動。

您可以將資料庫叢集參數設定為 `0`（停用）[neptune\$1lookup\$1cache](parameters.md#parameters-db-cluster-parameters-neptune_lookup_cache)，暫時停用資料庫叢集中所有執行個體的查詢快取。不過，一般而言，在特定執行個體上停用快取會更有意義，方法是將它們從 `R5d` 縮減至 `R5` 執行個體類型。

# Neptune 中的交易語意
<a name="transactions"></a>

Amazon Neptune 旨在透過資料圖形支援高度並行線上交易處理 (OLTP) 工作負載。[適用於 RDF 的 W3C SPARQL 查詢語言](https://www.w3.org/TR/rdf-sparql-query/)和 [Apache TinkerPop Gremlin 圖形周遊語言](http://tinkerpop.apache.org/gremlin.html)文件不會為並行查詢處理定義交易語意。由於 ACID 支援和定義良好的交易保證非常重要，因此我們會強制執行嚴格的語義，以協助避免資料異常。

本節會定義這些語義，並說明它們如何套用到 Neptune 中的一些常用案例。

**Topics**
+ [隔離層級的定義](transactions-isolation-levels.md)
+ [Neptune 中的交易隔離層級](transactions-neptune.md)
+ [Neptune 交易語義範例](transactions-examples.md)

# 隔離層級的定義
<a name="transactions-isolation-levels"></a>

`ACID` 中的 "I" 代表*隔離*。交易的隔離程度決定了其他並行交易可能影響其操作的資料有多少。

[SQL:1992 標準](http://www.contrib.andrew.cmu.edu/~shadow/sql/sql1992.txt) 建立了描述隔離層級的詞彙。它定義了兩個並行交易 (`Tx1` 和 `Tx2`) 之間可能發生的三種互動 (它稱為「現象」**)：
+ `Dirty read` – 當 `Tx1` 修改項目，然後 `Tx2` 在 `Tx1` 遞交了變更之前讀取該項目，就會發生此情況。然後，如果 `Tx1` 從未成功遞交變更或將其回復，則 `Tx2` 已讀取從未進入資料庫的值。
+ `Non-repeatable read` – 當 `Tx1` 讀取項目，接著 `Tx2` 修改或刪除該項目並遞交變更，然後 `Tx1` 嘗試重新讀取該項目時，便會發生此情況。`Tx1` 現在會讀取與之前不同的值，或發現該項目不再存在。
+ `Phantom read` – 當 `Tx1` 讀取一組滿足搜尋條件的項目，接著 `Tx2` 新增符合搜尋條件的新項目，然後 `Tx1` 重複搜尋時，便會發生此情況。`Tx1` 現在取得與之前不同的一組項目。

這三種類型的互動，每一種都可能導致資料庫中產生的資料不一致。

SQL:1992 標準定義了四種隔離層級，在三種互動類型以及它們可能產生的不一致性方面具有不同的保證。在所有四個層級，可以保證交易完全執行或完全不執行：
+ `READ UNCOMMITTED` – 允許所有三種互動 (亦即，已變更讀取、不可重複讀取及幽靈讀取)。
+ `READ COMMITTED` – 已變更讀取是不可行，但不可重複讀取和幽靈讀取卻可行。
+ `REPEATABLE READ` – 已變更讀取或不可重複讀取全都不可行，但幽靈讀取仍然可行。
+ `SERIALIZABLE` – 三種類型的互動現象都不能發生。

多版本並行控制 (MVCC) 允許另一種隔離，即 *SNAPSHOT* 隔離。這保證在交易開始時，交易可在存在之資料的快照上操作，而且其他交易都不能變更該快照。

# Neptune 中的交易隔離層級
<a name="transactions-neptune"></a>

Amazon Neptune 針對唯讀查詢和變動查詢實作不同的交易隔離層級。SPARQL 和 Gremlin 查詢會根據下列條件分類為唯讀或變動：
+ 在 SPARQL 中，讀取查詢 (`SELECT`、`ASK`、`CONSTRUCT` 和 `DESCRIBE`，如 [SPARQL 1.1 查詢語言](https://www.w3.org/TR/sparql11-query/)規格中所定義) 與變動查詢 (`INSERT` 和 `DELETE`，如 [SPARQL 1.1 更新](https://www.w3.org/TR/sparql11-update/)規格中所定義) 之間有明確的區別。

  請注意，Neptune 將多個一起提交的變動查詢 (例如，在 `POST` 訊息中，以分號分隔) 視為單一交易。其為保證作用的原子單位，不是成功就是失敗，若是失敗則會轉返部分變更。
+ 不過，在 Gremlin 中，Neptune 會根據是否包含任何查詢路徑步驟 (例如操縱資料的 `addE()`、`addV()`、`property()` 或 `drop()`) 將查詢分類為唯讀查詢或變動查詢。如果查詢包含任何這類路徑步驟，則會將其分類並做為變動查詢執行。

也可以在 Gremlin 中使用常設工作階段。如需詳細資訊，請參閱[Gremlin 指令碼型工作階段](access-graph-gremlin-sessions.md)。在這些工作階段中，所有查詢 (包括唯讀查詢) 都會在與寫入器端點上變動查詢相同的隔離下執行。

在 openCypher 中使用 Bolt 讀寫工作階段，所有查詢 (包括唯讀查詢) 都會在與寫入器端點上變動查詢相同的隔離下執行。

**Topics**
+ [Neptune 中的唯讀查詢隔離](#transactions-neptune-read-only)
+ [Neptune 中的變動查詢隔離](#transactions-neptune-mutation)
+ [使用鎖定等待逾時的衝突解決機制](#transactions-neptune-conflicts)
+ [範圍鎖定和錯誤衝突](#transactions-neptune-false-conflicts)

## Neptune 中的唯讀查詢隔離
<a name="transactions-neptune-read-only"></a>

Neptune 會依據快照隔離語義來評估唯讀查詢。這表示唯讀查詢會在邏輯上對查詢評估開始時所取得之資料庫的一致快照進行操作。然後，Neptune 可以保證不會發生以下任何現象：
+ `Dirty reads` – Neptune 中的唯讀查詢絕不會看到來自並行交易的未遞交資料。
+ `Non-repeatable reads` – 多次讀取相同資料的唯讀交易一律會取回相同的值。
+ `Phantom reads` – 唯讀交易絕不會讀取交易開始後新增的資料。

由於快照隔離是使用多版本並行控制 (MVCC) 來實現，因此唯讀查詢不需要鎖定資料，因此不會封鎖變動查詢。

僅供讀取複本僅接受唯讀查詢，因此針對僅供讀取複本的所有查詢都會依據 `SNAPSHOT` 隔離語意執行。

查詢僅供讀取複本時，唯一額外的考量是寫入器和僅供讀取複本之間可能會有較短的複寫延遲。這表示對寫入器所做的更新可能需要很短的時間傳播到您正在從中讀取的僅供讀取複本。實際複寫時間取決於針對主要執行個體的寫入負載。Neptune 架構支援低延遲複寫，而且複寫延遲是以 Amazon CloudWatch 指標進行檢測。

儘管如此，由於 `SNAPSHOT` 隔離層級，讀取查詢永遠都會看到資料庫的一致狀態，即使不是最新的查詢也一樣。

如果您需要強力保證查詢會觀察先前更新的結果，請將查詢傳送到寫入器端點本身，而不是傳送到僅供讀取複本。

## Neptune 中的變動查詢隔離
<a name="transactions-neptune-mutation"></a>

做為變動查詢一部分進行的讀取會在 `READ COMMITTED` 交易隔離下執行，以排除已變更讀取的可能性。超越對 `READ COMMITTED` 交易隔離提供的一般保證，Neptune 強力保證，既不會發生 `NON-REPEATABLE` 讀取，也不會發生 `PHANTOM` 讀取。

這些強力保證是透過讀取資料時鎖定記錄和記錄範圍來實現。這可防止並行交易在讀取後對索引範圍進行插入或刪除，因而保證可重複讀取。

**注意**  
不過，並行變動交易 `Tx2` 可能會在變動交易 `Tx1` 啟動之後開始，並可能在 `Tx1` 鎖定資料以讀取變更之前遞交變更。在此情況下，`Tx1` 會看到 `Tx2` 的變更，宛如在 `Tx1` 啟動之前，`Tx2` 就已完成。因為這只適用於遞交的變更，所以 `dirty read` 永遠不會發生。

若要了解 Neptune 用於變動查詢的鎖定機制，首先了解 Neptune [圖形資料模型](feature-overview-data-model.md) 和 [索引策略](feature-overview-storage-indexing.md) 的詳細資訊很有幫助。Neptune 會使用三個索引 (即 `SPOG`、`POGS` 和 `GPSO`) 管理資料。

為了實現 `READ COMMITTED` 交易層級的可重複讀取，Neptune 會在使用中的索引中採取範圍鎖定。例如，如果變動查詢讀取名為 `person1` 之頂點的所有屬性和傳出邊緣，則節點會在讀取資料之前，鎖定 `SPOG` 索引中字首 `S=person1` 所定義的整個範圍。

使用其他索引時，也適用相同的機制。例如，當變動交易使用 `POGS` 索引，查詢所指定邊緣標籤的所有來源目標頂點時，`P` 位置中的邊緣標籤範圍將被鎖定。任何並行交易，無論它是唯讀或變動查詢，仍可在鎖定的範圍內執行讀取。不過，任何涉及在鎖定字首範圍內插入或刪除新記錄的變動都需要獨佔鎖定，而且將予以防止。

換言之，當變動交易讀取某個索引範圍時，強力保證在讀取交易結束之前，任何並行交易都不會修改此範圍。這可保證 `non-repeatable reads` 不會發生。

## 使用鎖定等待逾時的衝突解決機制
<a name="transactions-neptune-conflicts"></a>

如果第二個交易嘗試修改第一個交易已鎖定之範圍中的記錄，Neptune 會立即偵測到衝突並封鎖第二個交易。

如果未偵測到相依性死結，Neptune 會自動套用鎖定等待逾時機制。其中封鎖的交易會等待最多 60 秒，讓保留鎖定的交易完成並釋出鎖定。
+ 如果鎖定等待逾時在釋出鎖定之前過期，則會復原封鎖的交易。
+ 如果鎖定在鎖定等待逾時內釋出，則第二個交易會解除封鎖並可以成功完成，而不需要重試。

不過，如果 Neptune 在兩個交易之間偵測到相依性死結，則無法自動調解衝突。在此情況下，Neptune 會立即取消並復原兩個交易之一，而不會啟動鎖定等待逾時。Neptune 會盡最大努力復原已插入或刪除最少記錄的交易。

### 測量鎖定等待時間 （引擎 ≥ 1.4.5.0)
<a name="transactions-neptune-lock-wait-metrics"></a>

從引擎 1.4.5.0 版開始，您可以使用兩個 slow-query-log 計數器來觀察變動查詢的封鎖時間：


| 計數器 | Description | 
| --- | --- | 
| `sharedLocksWaitTimeMillis` | 等待取得共用 (S) 鎖定所花費的時間，允許多個讀取器，但封鎖寫入器。 | 
| `exclusiveLocksWaitTimeMillis` | 等待取得專屬 (X) 鎖定所花費的時間，這會封鎖所有其他存取。 | 

只有當您啟用慢速查詢登入`debug`模式 () 時，這兩個欄位才會出現在 `storageCounters` 物件中`neptune_enable_slow_query_log=debug`。

**提示**  
如果 `sharedLocksWaitTimeMillis + exclusiveLocksWaitTimeMillis`接近查詢的 `overallRunTimeMs`，查詢會受到鎖定爭用，而不是 CPU、網路或 I/O 的瓶頸。

減少爭用的實際秘訣：
+ **交錯衝突任務** – 在較低的使用者活動期間執行繁重的批次變動。
+ 將**大型變動分解為較小的區塊** – 較小的交易會鎖定更短的時間，減少逾時的機會。

## 範圍鎖定和錯誤衝突
<a name="transactions-neptune-false-conflicts"></a>

Neptune 會使用間隙鎖定採取範圍鎖定。間隙鎖定是鎖定索引記錄之間的間隙，或鎖定第一個索引記錄之前或最後一個索引記錄之後的間隙。

Neptune 使用所謂的字典資料表，將數值 ID 值與特定字串常值建立關聯。以下是這類 Neptune 字典的範例狀態：資料表：


| String | ID | 
| --- | --- | 
| type | 1 | 
| default\$1graph | 2 | 
| person\$13 | 3 | 
| person\$11 | 5 | 
| knows | 6 | 
| person\$12 | 7 | 
| age | 8 | 
| edge\$11 | 9 | 
| lives\$1in | 10 | 
| New York | 11 | 
| 個人 | 12 | 
| Place | 13 | 
| edge\$12 | 14 | 

上面的字串屬於一個屬性圖模型，但這些概念也同樣適用於所有 RDF 圖形模型。

SPOG (Subject-Predicate-Object\$1Graph) 索引的對應狀態會顯示在下面的左側。右側會顯示對應字串，以協助了解索引資料的含義。


| S (ID) | P (ID) | O (ID) | G (ID) |  | S (字串) | P (字串) | O (字串) | G (字串) | 
| --- | --- | --- | --- | --- | --- | --- | --- | --- | 
| 3 | 1 | 12 | 2 |  | person\$13 | type | 個人 | default\$1graph | 
| 5 | 1 | 12 | 2 |  | person\$11 | type | 個人 | default\$1graph | 
| 5 | 6 | 3 | 9 |  | person\$11 | knows | person\$13 | edge\$11 | 
| 5 | 8 | 40 | 2 |  | person\$11 | age | 40 | default\$1graph | 
| 5 | 10 | 11 | 14 |  | person\$11 | lives\$1in | New York | edge\$12 | 
| 7 | 1 | 12 | 2 |  | person\$12 | type | 個人 | default\$1graph | 
| 11 | 1 | 13 | 2 |  | New York | type | Place | default\$1graph | 

現在，如果變動查詢讀取名為 `person_1` 之頂點的所有屬性和傳出邊緣，則節點會在讀取資料之前，鎖定 SPOG 索引中字首 `S=person_1` 所定義的整個範圍。範圍鎖定會在所有相符的記錄和第一筆不相符的記錄上放置間隙鎖定。相符記錄將遭到鎖定，而不相符的記錄將不會遭到鎖定。Neptune 將放置間隙鎖定，如下所示：
+ ` 5 1 12 2 ` *(間隙 1)*
+ ` 5 6 3 9 ` *(間隙 2)*
+ ` 5 8 40 2 ` *(間隙 3)*
+ ` 5 10 11 14 ` *(間隙 4)*
+ ` 7 1 12 2 ` *(間隙 5)*

這會鎖定下列記錄：
+ ` 5 1 12 2`
+ ` 5 6 3 9`
+ ` 5 8 40 2`
+ ` 5 10 11 14`

在此狀態下，下列操作會遭合法封鎖：
+ 插入 `S=person_1` 的新屬性或邊緣。不同於 `type` 的新屬性或新邊緣必須進入間隙 2、間隙 3、間隙 4 或間隙 5，它們全都遭到鎖定。
+ 刪除任何現有記錄。

同時，一些並行作將遭錯誤地封鎖 (產生錯誤衝突）：
+ `S=person_3` 的任何屬性或邊緣插入都會遭到封鎖，因為它們必須進入間隙 1。
+ 在 3 與 5 之間獲指派 ID 的任何新頂點插入將遭封鎖，因為它必須進入間隙 1。
+ 在 5 與 7 之間獲指派 ID 的任何新頂點插入將遭封鎖，因為它必須進入間隙 5。

間隙鎖定不夠精確，無法鎖定一個特定述詞的間隙 (例如，鎖定述詞 `S=5` 的間隙 5)。

範圍鎖定只會放置在發生讀取的索引中。在上述情況下，記錄僅鎖定在 SPOG 索引中，而不是在 POGS 或 GPSO 中。查詢的讀取可能跨所有索引上執行，取決於存取模式，這些模式可以使用 `explain` API 來列出 (適用於 [Sparql](sparql-explain-examples.md) 和 [Gremlin](gremlin-explain.md))。

**注意**  
也可以採取間隙鎖定，對基礎索引進行安全的並行更新，這也可能導致錯誤的衝突。放置這些間隙鎖定與交易所執行的隔離層級或讀取操作無關。

不僅在「並行」**交易由於間隙鎖定而發生衝突時，可能發生錯誤衝突，還可能在某些情況下，於任何類型的失敗之後重試交易時也會發生。如果失敗觸發的復原仍在進行中，且先前針對交易採取的鎖定尚未完全釋放，則重試將會遇到錯誤的衝突並失敗。

在高負載下，您通常會發現 3-4% 的寫入查詢會由於錯誤的衝突而失敗。對於外部用戶端，這類錯誤的衝突很難預測，應該使用[重試](transactions-exceptions.md)來處理。

# Neptune 交易語義範例
<a name="transactions-examples"></a>

以下範例說明 Amazon Neptune 中交易語義的不同使用案例。

**Topics**
+ [屬性的條件式插入](#transactions-examples-conditional-insertion)
+ [屬性值唯一性](#transactions-examples-unique-property)
+ [條件式屬性變更](#transactions-examples-conditional-edit)
+ [取代屬性](#transactions-examples-replace)
+ [避免懸置元素](#transactions-examples-dangling)

## 範例 1 - 僅在屬性不存在時插入屬性
<a name="transactions-examples-conditional-insertion"></a>

假設您想要確保屬性只設定一次。例如，假設多個查詢正在嘗試同時將信用分數指派給人員。您只想要插入一個屬性執行個體，而其他查詢會失敗，因為已設定屬性。

```
# GREMLIN:
g.V('person1').hasLabel('Person').coalesce(has('creditScore'), property('creditScore', 'AAA+'))

# SPARQL:
INSERT { :person1 :creditScore "AAA+" .}
WHERE  { :person1 rdf:type :Person .
         FILTER NOT EXISTS { :person1 :creditScore ?o .} }
```

Gremlin `property()` 步驟會插入具有所指定索引鍵和值的屬性。`coalesce()` 步驟會在第一個步驟中執行第一個引數，如果失敗，則會執行第二個步驟：

在插入所指定 `person1` 頂點的 `creditScore` 屬性值之前，交易必須嘗試為 `person1` 讀取可能不存在的 `creditScore` 值。此嘗試讀取會鎖定 `SPOG` 索引中 `S=person1` 和 `P=creditScore` 的 `SP` 範圍，其中 `creditScore` 值存在或將被寫入。

採取此範圍鎖定可防止任何並行交易同時插入 `creditScore` 值。有多個平行交易時，一次最多一個平行交易可以更新該值。這會排除建立多個 `creditScore` 屬性的異常。

## 範例 2 - 宣告屬性值在全域上是唯一的
<a name="transactions-examples-unique-property"></a>

假設您想要插入社會安全號碼做為主索引鍵的人員。您想要變動查詢保證，在全域層級中，資料庫中沒有任何其他人具有相同的社會安全號碼：

```
# GREMLIN:
g.V().has('ssn', 123456789).fold()
  .coalesce(__.unfold(),
            __.addV('Person').property('name', 'John Doe').property('ssn', 123456789'))

# SPARQL:
INSERT { :person1 rdf:type :Person .
         :person1 :name "John Doe" .
         :person1 :ssn 123456789 .}
WHERE  { FILTER NOT EXISTS { ?person :ssn 123456789 } }
```

此範例與上述範例類似。主要差別在於範圍鎖定是針對 `POGS` 索引而非 `SPOG` 索引採取的。

執行查詢的交易必須讀取模式 (`?person :ssn 123456789`)，其中繫結 `P` 和 `O` 位置。範圍鎖定是針對 `P=ssn` 和 `O=123456789` 的 `POGS` 索引採取的。
+ 如果模式的確存在，則不會採取任何動作。
+ 如果不存在，鎖定會防止任何並行交易也插入該社會安全號碼

## 範例 3 - 如果另一個屬性具有指定值，則變更屬性
<a name="transactions-examples-conditional-edit"></a>

假設遊戲中的各種事件將人物從第一層移到第二層，並將設為零的新 `level2Score` 屬性指派給他們。您需要確保這類交易的多個並行執行個體無法建立層級二分數屬性的多個執行個體。Gremlin 和 SPARQL 中的查詢可能看起來如下所示。

```
# GREMLIN:
g.V('person1').hasLabel('Person').has('level', 1)
 .property('level2Score', 0)
 .property(Cardinality.single, 'level', 2)

# SPARQL:
DELETE { :person1 :level 1 .}
INSERT { :person1 :level2Score 0 .
         :person1 :level 2 .}
WHERE  { :person1 rdf:type :Person .
         :person1 :level 1 .}
```

在 Gremlin 中，指定 `Cardinality.single` 時，`property()` 步驟會新增屬性，或將現有的屬性值取代為指定的新值。

屬性值的任何更新 (例如將 `level` 從 1 增加到 2) 會實作為刪除目前記錄，並使用新的屬性值插入新記錄。在此情況下，會刪除層級編號 1 的記錄，並重新插入層級編號 2 的記錄。

若要讓交易能夠新增 `level`，並將 `level2Score` 從 1 更新到 2，必須先驗證 `level` 值目前是否等於 1。執行此動作時，它會對 `SPOG` 索引中 `S=person1`、`P=level` 和 `O=1` 的 `SPO` 字首採取範圍鎖定。此鎖定可防止並行交易刪除版本 1 三元組，因此不可能發生起衝突的並行更新。

## 範例 4 - 取代現有屬性
<a name="transactions-examples-replace"></a>

特定事件可能會將人員的信用分數更新為新值 (這裡指的是 `BBB`)。但您想要確保該類型的並行事件無法為人員建立多個信用分數屬性。

```
# GREMLIN:
g.V('person1').hasLabel('Person')
 .sideEffect(properties('creditScore').drop())
 .property('creditScore', 'BBB')

# SPARQL:
DELETE { :person1 :creditScore ?o .}
INSERT { :person1 :creditScore "BBB" .}
WHERE  { :person1 rdf:type :Person .
         :person1 :creditScore ?o .}
```

此案例與範例 3 類似，差別在於不是鎖定 `SPO` 字首，而是 Neptune 只會鎖定具有 `S=person1` 和 `P=creditScore` 的 `SP` 字首。這可防止並行交易插入或刪除任何具有 `person1` 主旨之 `creditScore` 屬性的三元組。

## 範例 5 - 避免懸置屬性或邊緣
<a name="transactions-examples-dangling"></a>

實體上的更新不應留下懸置元素，也就是與未輸入之實體相關聯的屬性或邊緣。這只是 SPARQL 中的問題，因為 Gremlin 具有內建限制條件來防止懸置元素。

```
# SPARQL:
tx1: INSERT { :person1 :age 23 } WHERE { :person1 rdf:type :Person }
tx2: DELETE { :person1 ?p ?o }
```

`INSERT` 查詢必須讀取和鎖定 `SPOG` 索引 `O=Person` 中具有 `S=person1` 和 `P=rdf:type`,的 `SPO` 字首。鎖定可防止 `DELETE` 查詢平行成功。

在這兩個查詢 (嘗試刪除 `:person1 rdf:type :Person` 記錄的 `DELETE` 查詢，以及讀取記錄並在 `SPOG` 索引中的 `SPO` 上建立範圍的 `INSERT` 查詢) 之間的競爭中，可能會產生以下結果：
+ 如果 `INSERT` 查詢在 `DELETE` 查詢讀取並刪除 `:person1` 的所有記錄之前遞交，則 `:person1` 會完全從資料庫中移除，包括新插入的記錄。
+ 如果 `DELETE` 查詢在 `INSERT` 查詢嘗試讀取 `:person1 rdf:type :Person` 記錄之前遞交，則讀取會觀察遞交的變更。也就是說，它找不到任何 `:person1 rdf:type :Person` 記錄，因此變成無操作。
+ 如果 `INSERT` 查詢在 `DELETE` 查詢讀取之前讀取，則 `:person1 rdf:type :Person` 三元組會遭到鎖定，而且 `DELETE` 查詢會遭到封鎖，直到 INSERT 查詢遞交為止，如先前的第一個案例一樣。
+ 如果 `DELETE` 在 `INSERT` 查詢之前讀取，而且 `INSERT` 查詢嘗試讀取，並對記錄的 `SPO` 字首採取鎖定，則會偵測到衝突。這是因為三元組已標記為移除，然後 `INSERT` 失敗。

在所有這些不同的可能事件序列中，不會建立懸置邊緣。

# Amazon Neptune 資料庫叢集和執行個體
<a name="feature-overview-db-clusters"></a>

Amazon Neptune「資料庫叢集」**會透過查詢管理對資料的存取。一個叢集包含：
+ 一個「主要資料庫執行個體」**。
+ 最多 15 個「僅供讀取複本資料庫執行個體」**。

叢集中的所有執行個體共用相同的[基礎受管儲存磁碟區](feature-overview-storage.md)，這是專為可靠性和高可用性而設計的。

您可以透過 [Neptune 端點](feature-overview-endpoints.md)連線至資料庫叢集中的資料庫執行個體。

## Neptune 資料庫叢集中的主要資料庫執行個體
<a name="feature-overview-primary-instance"></a>

主要資料庫執行個體會協調對資料庫叢集的基礎儲存磁碟區的所有寫入操作。它也支援讀取操作。

Neptune 資料庫叢集中只能有一個主要資料庫執行個體。如果主要執行個體變得無法使用，Neptune 會自動容錯移轉至具有您所指定優先順序的其中一個僅供讀取複本執行個體。

## Neptune 資料庫叢集中的僅供讀取複本資料庫執行個體
<a name="feature-overview-read-replicas"></a>

在建立資料庫叢集的主要執行個體之後，您可以在資料庫叢集中最多建立 15 個僅供讀取複本執行個體，來支援唯讀查詢。

Aurora 僅供讀取複本很適用於擴展讀取容量，因為完全專用於叢集磁碟區上的讀取操作。所有寫入操作是由主要執行個體管理。每個僅供讀取複本資料庫執行個體都有自己的端點。

由於叢集儲存磁碟區是在叢集中的所有執行個體之間共用，因此所有僅供讀取複本執行個體都會針對查詢結果傳回相同的資料，複寫延遲非常短。在主要執行個體寫入更新之後，此延遲通常遠低於 100 毫秒，但在寫入操作的數量非常大時，此延遲通常會稍長一些。

在不同的可用區域中具有一或多個可用的僅供讀取複本執行個體可以提高可用性，因為僅供讀取複本會做為主要執行個體的容錯移轉目標。亦即，如果主要執行個體失敗，則 Neptune 會提升僅供讀取複本以成為主要執行個體。當發生此情況時，若重新啟動提升的執行個體，會發生短暫的中斷，在此期間對主要執行個體提出的讀取和寫入請求會由於例外狀況而失敗。

相反地，如果您的資料庫叢集不包含任何僅供讀取複本執行個體，則當主要執行個體失敗時，資料庫叢集仍無法使用，直到重新建立為止。重新建立主要執行個體所花費的時間比提升僅供讀取複本要長得多。

為了確保高可用性，建議您建立一或多個僅供讀取複本執行個體，這些執行個體具有與主要執行個體相同的資料庫執行個體類別，且位於與主要執行個體不同的可用區域。請參閱 [Neptune 資料庫叢集的容錯能力](backup-restore-overview-fault-tolerance.md)。

透過主控台，您只要在建立資料庫叢集時指定 Multi-AZ (異地同步備份)，即可輕鬆建立異地同步備份部署。如果資料庫叢集位於單一可用區域中，您可以在不同的可用區域新增 Neptune 複本，使其變成多重可用區資料庫叢集。

**注意**  
您無法為未加密的 Neptune 資料庫叢集建立加密的僅供讀取複本執行個體，也無法為加密的 Neptune 資料庫叢集建立未加密的僅供讀取複本執行個體。

如需如何建立 Neptune 僅供讀取複本資料庫執行個體的詳細資訊，請參閱 [使用主控台建立 Neptune 讀取器執行個體](manage-console-create-replica.md)。

## 調整 Neptune 資料庫叢集中資料庫執行個體的大小
<a name="feature-overview-sizing-instances"></a>

根據您的 CPU 和記憶體需求調整 Neptune 資料庫叢集中執行個體的大小。執行個體上的 vCPU 數目會決定處理傳入查詢的查詢執行緒數目。執行個體上的記憶體數量會決定緩衝區快取的大小，用於儲存從基礎儲存磁碟區擷取的資料頁面副本。

每個 Neptune 資料庫執行個體都具有相當於該執行個體上 vCPU 數目 2 倍的查詢執行緒數目。例如，具有 16 個 vCPU 的 `r5.4xlarge` 具有 32 個查詢執行緒，因此可以同時處理 32 個查詢。

在所有查詢執行緒都被佔用時到達的其他查詢會放入伺服器端佇列中，並在查詢執行緒變成可用時以 FIFO 的方式進行處理。此伺服器端佇列可保留約 8000 個待定請求。一旦裝滿，Neptune 會以 `ThrottlingException` 回應其他請求。您可以使用 `MainRequestQueuePendingRequests` CloudWatch 指標，或使用 [Gremlin 查詢狀態端點](gremlin-api-status.md)搭配 `includeWaiting` 參數，來監控待定的請求數目

從用戶端的角度來看，查詢執行時間除了實際執行查詢所花費的時間之外，還包括花費在佇列中的任何時間。

利用主要資料庫執行個體上所有查詢執行緒的持續並行寫入負載，理想情況下會顯示 90% 以上的 CPU 使用率，這指示伺服器上的所有查詢執行緒都在積極參與執行有用的工作。不過，即使在持續的並行寫入負載下，實際 CPU 使用率通常也會稍低一些。這通常是因為查詢執行緒正在等待基礎儲存磁碟區的 I/O 操作完成。Neptune 會使用仲裁寫入，跨三個可用區域製作六個資料副本，而這六個儲存節點中的四個必須確認寫入，才能將其視為持久性。當查詢執行緒從儲存磁碟區等待此仲裁時，它會停滯，從而降低 CPU 使用率。

如果您有一個序列寫入負載，您正在其中執行一個接一個的寫入，並等待第一個寫入完成後再開始下一個，您可以預期 CPU 使用率仍會降低。確切的數量將是 vCPU 和查詢執行緒數目的函數 (查詢執行緒越多，每個查詢的整體 CPU 就越少)，而等待 I/O 會導致減少一些。

如需有關如何最好地調整資料庫執行個體大小的詳細資訊，請參閱 [選擇 Amazon Neptune 的執行個體類型](instance-types.md)。如需每個執行個體類型的定價，請參閱 [Neptune 定價頁面](https://aws.amazon.com/neptune/pricing/)。

## 在 Neptune 中監控資料庫執行個體
<a name="feature-overview-monitoring-instances"></a>

您可以在 Neptune 中使用 CloudWatch 指標來監控資料庫執行個體的效能，並追蹤用戶端觀察到的查詢延遲。請參閱 [使用 CloudWatch 監控 Neptune 中的資料庫執行個體效能](cloudwatch-monitoring-instances.md)。

# Amazon Neptune 儲存體、可靠性和可用性
<a name="feature-overview-storage"></a>

Amazon Neptune 會使用分散式和共用儲存架構，該架構會隨著資料庫儲存需求的增長而自動擴展。

Neptune 資料會儲存在叢集磁碟區中，該磁碟區是單一虛擬磁碟區，使用非揮發性記憶體快速 (NVMe) SSD 型磁碟機。叢集磁碟區包含邏輯區塊 (稱為區段) 的集合。這些區段的每一個都會獲配置 10 GB 的儲存體。每個區段中的資料會複寫至六個副本，然後在資料庫叢集所在 AWS 區域中的三個可用區域 (AZ) 之間進行配置。

建立 Neptune 資料庫叢集時，會為其配置 10 GB 的單一區段。當資料量增加並超過目前配置的儲存體時，Neptune 會透過新增區段來自動擴充叢集磁碟區。在所有支援的區域中，Neptune 叢集磁碟區最多可增長至 128 TiB，但中國和 GovCloud 除外，在那裡最多只能增長至 64 TiB。不過，對於 [版本：1.0.2.2 (2020 年 3 月 9 日)](engine-releases-1.0.2.2.md) 之前的版本引擎，所有區域中叢集磁碟區的大小限制為 64 TiB。

資料庫叢集磁碟區包含您的所有使用者資料、索引和字典 (如 [Neptune 圖形資料模型。](feature-overview-data-model.md) 一節所述)，以及內部中繼資料，例如內部交易日誌。所有此圖形資料 (包括索引和內部日誌) 不得超過叢集磁碟區的大小上限。

## I/O 優化儲存選項
<a name="feature-overview-storage-iops"></a>

Neptune 提供兩種儲存定價模式：
+ **標準儲存** — 標準儲存體可為中至低 I/O 使用量的應用程式提供具經濟效益的資料庫儲存。
+ **I/O 優化儲存** — 若使用 I/O 優化儲存，您只需以高於標準儲存的成本為所使用的儲存體付費，而且無需為使用的 I/O 付費。

  I/O 優化儲存的設計符合 I/O 密集型圖形工作負載的需求，並具有低延遲要求和一致的 I/O 輸送量的低延遲。

  如需詳細資訊，請參閱 [I/O 優化儲存](storage-types.md#provisioned-iops-storage)。

## Neptune 儲存體配置
<a name="feature-overview-storage-allocation"></a>

即使 Neptune 叢集磁碟區可以增長至 128 TiB (或在少數區域中，64 TiB)，您也只需為實際配置的空間支付費用。配置的總空間是由儲存*高水位*決定，這是在叢集磁碟區存在期間隨時配置給叢集磁碟區的最大容量。

這表示，即使從叢集磁碟區移除使用者資料，例如透過捨棄查詢 (例如 `g.V().drop()`)，總配置的空間仍保持不變。Neptune 會自動最佳化未使用的配置空間，以供日後重複使用。

除了使用者資料之外，另外兩種類型的內容會耗用內部儲存空間，即字典資料和內部交易日誌。雖然字典資料與圖形資料一起儲存，但即使刪除了它支援的圖形資料後，它還是會無限期地存在，這表示如果重新引入資料，可以重複使用這些項目。內部日誌資料儲存在個別的內部存儲空間中，該儲存空間具有自己的高水位。當內部日誌到期時，它所佔用的儲存體可以重複用於其他日誌，但不能用於圖形資料。已配置給日誌的內部空間量會包含在 `VolumeBytesUsed` [CloudWatch 指標](cloudwatch.md)所報告的總空間中。

檢查 [儲存體最佳實務](#feature-overview-storage-best-practices) 取得將配置的儲存體保持在下限並重複使用空間的方法。

## Neptune 儲存計費
<a name="feature-overview-storage-billing"></a>

儲存成本是根據儲存*高水位*計費，如上所述。雖然您的資料會複寫為六個副本，但您只需為一份資料副本支付費用。

您可以透過監控 `VolumeBytesUsed` CloudWatch 指標來判斷資料庫叢集目前的儲存高水位 (請參閱 [使用 Amazon CloudWatch 監控 Neptune](cloudwatch.md))。

其他可能會影響 Neptune 儲存成本的因素包括資料庫快照和備份，這些快照和備份會以備份儲存體分別計費，並以 Neptune 儲存成本為基礎 (請參閱 [有助於管理 Neptune 備份儲存體的 CloudWatch 指標](backup-restore-overview-metrics.md))。

不過，如果您建立資料庫的[複製](manage-console-cloning.md)，複製會指向資料庫叢集本身使用的同一叢集磁碟區，因此原始資料不會產生額外的儲存費用。對複製的後續變更會使用[寫入時複製通訊協定](manage-console-cloning.md#manage-console-cloning-protocol)，並確實產生額外的儲存成本。

如需更多的 Neptune 定價資訊，請參閱 [Amazon Neptune 定價](https://aws.amazon.com/neptune/pricing)。

## Neptune 儲存體最佳實務
<a name="feature-overview-storage-best-practices"></a>

由於某些類型的資料會耗用 Neptune 中的永久儲存體，因此請使用下列最佳實務來避免儲存體增長時出現大量激增的情況：
+ 在設計圖形資料模型時，請盡可能避免使用本質為暫時性的屬性索引鍵和使用者面向值。
+ 如果您打算對資料模型進行變更，請不要使用新模型將資料載入至現有的資料庫叢集，直到使用[快速重設 API](manage-console-fast-reset.md) 清除該資料庫叢集中的資料為止。最好的做法通常是將使用新模型的資料載入至新的資料庫叢集。
+ 對大量資料操作的交易會產生相應的大型內部日誌，這可能會永久增加內部日誌空間的高水位。例如，刪除資料庫叢集中所有資料的單一交易可能會產生巨大的內部日誌，該日誌需要配置大量內部儲存空間，進而永久減少可用於圖形資料的空間。

  為了避免發生這種情況，請將大型交易分割為較小的交易，並在它們之間留出時間，以便相關聯的內部日誌有機會過期並釋放其內部存儲空間，以供後續日誌重複使用。
+ 如需監控 Neptune 叢集磁碟區的增長情況，您可以在 `VolumeBytesUsed` CloudWatch 指標上設定 CloudWatch 警示。如果您的資料達到叢集磁碟區的大小上限，這可能會特別有用。如需詳細資訊，請參閱[使用 Amazon CloudWatch 警示](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/AlarmThatSendsEmail.html)。

當您有大量未使用的配置空間時，縮減資料庫叢集使用的儲存空間的唯一方法是匯出圖形中的所有資料，然後將其重新載入至新的資料庫叢集。如需從資料庫叢集匯出資料的簡單方法，請參閱 [Neptune 的資料匯出服務和公用程式](machine-learning-data-export.md)，以及如需將資料匯回 Neptune 的簡單方法，請參閱 [Neptune 的大量載入器](bulk-load.md)。

**注意**  
建立和還原[快照](backup-restore-restore-snapshot.md)並不會減少為資料庫叢集配置的儲存空間量，因為快照會保留叢集基礎儲存體的原始映像。如果有大量配置的儲存裝置未使用，則縮減所配置之儲存空間量的唯一方法是匯出您的圖形資料，然後將其重新載入至新的資料庫叢集。

## Amazon Neptune 儲存體可靠性和高可用性
<a name="feature-overview-storage-reliability"></a>

Amazon Neptune 的設計目的是要既可靠、耐用且容錯。

在三個可用區域 (AZ) 之間維護六個 Neptune 資料副本的事實，可確保資料的儲存體具有高耐用性，因而資料遺失的可能性極低。無論可用區域中是否有資料庫執行個體，資料都會跨這些可用區域自動複寫，而且複寫數量與您叢集中的資料庫執行個體數目無關。

這表示您可以快速新增僅供讀取複本，因為 Neptune 不會製作圖形資料的新副本。相反地，僅供讀取複本會連線至已包含您資料的叢集磁碟區。同樣地，移除僅供讀取複本並不會移除任何基礎資料。

您只能在刪除叢集磁碟區的所有資料庫執行個體之後刪除該叢集磁碟區及其資料。

Neptune 也會自動偵測在組成叢集磁碟區的區段中所發生的失敗。當區段中的資料副本損毀時，Neptune 會立即修復該區段，進而使用相同區段內的其他資料副本，以確保修復的資料是最新的。因此，Neptune 可避免資料遺失並減少執行時間點還原以從磁碟失敗復原的需求。

# 連線至 Amazon Neptune 端點
<a name="feature-overview-endpoints"></a>

Amazon Neptune 會使用資料庫執行個體的叢集，而非單一執行個體。每個 Neptune 連線都由特定的資料庫執行個體處理。當您連線至 Neptune 叢集時，您指定的主機名稱和連接埠會指向稱為「端點」**的中繼處理常式。端點為包含主機地址和連接埠的 URL。Neptune 端點使用加密的 Transport Layer Security/Secure Sockets Layer (TLS/SSL) 連線。

Neptune 會使用端點機制來抽象化這些連線，以便您不必對主機名稱進行硬式編碼，或撰寫您自己的邏輯，在某些資料庫執行個體無法使用時重新路由連線。

使用端點，您可以將每個連線映射至適當的執行個體或執行個體群組，取決於您的使用案例。自訂端點可讓您連線至資料庫執行個體的子集。下列端點可在 Neptune 資料庫叢集中使用。

## Neptune 叢集端點
<a name="feature-overview-cluster-endpoints"></a>

叢集端點為 Neptune 資料庫叢集的端點，其會連線至該資料庫叢集目前的主要資料庫執行個體。每個 Neptune 資料庫叢集具有一個叢集端點和一個主要資料庫執行個體。

叢集端點可為資料庫叢集的讀寫連線提供容錯移轉支援。對資料庫叢集上的所有寫入操作，包括插入、更新、刪除和資料定義語言 (DDL) 變更使用叢集端點。您也可以對讀取操作 (例如查詢) 使用叢集端點。

如果資料庫叢集目前的主要資料庫執行個體失敗，Neptune 會自動容錯移轉至新的主要資料庫執行個體。容錯移轉期間，資料庫叢集會繼續從新的主要資料庫執行個體對叢集端點提供連線請求，將對服務的中斷降到最低。

以下範例說明 Neptune 資料庫叢集的叢集端點。

`mydbcluster.cluster-123456789012.us-east-1.neptune.amazonaws.com:8182`

## Neptune 讀取器端點
<a name="feature-overview-reader-endpoints"></a>

讀取器端點為 Neptune 資料庫叢集的端點，其會連線至該資料庫叢集其中一個可用的 Neptune 複本。每個 Neptune 資料庫叢集都有一個讀取器端點。如果有多個 Neptune 複本，讀取器端點會將每個連線請求導向其中一個 Neptune 複本。

讀取器端點可為資料庫叢集的唯讀連線提供循環配置資源路由。對讀取操作 (例如 查詢) 使用讀取器端點。

除非您有單一執行個體叢集 (沒有僅供讀取複本的叢集)，否則無法使用讀取器端點進行寫入作業。在這種情況下 (以及只有在這種情況下)，讀取器可以用於寫入操作以及讀取操作。

讀取器端點循環配置資源路由的運作方式是改變 DNS 項目指向的主機。每當您解析 DNS，就會取得不同的 IP，且對這些 IP 開放連線。建立連線後，所有對該連線的請求都會傳送到同一主機。用戶端必須再次建立新的連線和解析 DNS 記錄，以取得可能不同的僅供讀取複本的連線。

**注意**  
WebSockets 連線通常會維持很長一段時間。若要獲得不同的僅供讀取複本，請執行下列動作：  
確保您的用戶端於每次連線時解析 DNS 項目。
關閉連線並重新連線。

不同的用戶端軟體可能會以不同的方式解析 DNS。例如，如果您的用戶端解析 DNS，然後將 IP 用於每一個連線，則軟體會將所有請求導向單一主機。

用戶端或代理伺服器的 DNS 快取，會從快取將 DNS 名稱解析至同一個端點。這對循環配置資源路由和容錯移轉情況都構成問題。

**注意**  
停用所有 DNS 快取設定，以強制每次執行 DNS 解析。

資料庫叢集會在可用的 Neptune 複本間對讀取器端點分配連線請求。如果資料庫叢集僅包含一個主要資料庫執行個體，讀取器端點會從主要資料庫執行個體提供連接請求。如果已為該資料庫叢集建立 Neptune 複本，讀取器端點會繼續從新的 Neptune 複本對讀取器端點提供連線請求，將對服務的中斷降到最低。

下列範例說明 Neptune 資料庫叢集的讀取器端點。

`mydbcluster.cluster-ro-123456789012.us-east-1.neptune.amazonaws.com:8182`

## Neptune 執行個體端點
<a name="feature-overview-instance-endpoints"></a>

執行個體端點為 Neptune 資料庫叢集中資料庫執行個體的端點，其會連線至該特定資料庫執行個體。資料庫叢集中的每個資料庫執行個體，不論執行個體類型為何，都有自己的唯一執行個體端點。因此，資料庫叢集目前的主要資料庫執行個體有一個執行個體端點。資料庫叢集的每一個 Neptune 複本也有一個執行個體端點。

執行個體端點對資料庫叢集的連線提供直接控制，使用叢集端點或讀取器端點的案例可能不適用。例如，根據工作負載類型而定，您的用戶端應用程式可能需要精細負載平衡。在此情況下，您可以設定多個用戶端連線至資料庫叢集中的不同 Neptune 複本，以分配讀取工作負載。

下列範例說明 Neptune 資料庫叢集中資料庫執行個體的執行個體端點。

`mydbinstance.123456789012.us-east-1.neptune.amazonaws.com:8182`

## Neptune 自訂端點
<a name="feature-overview-custom-endpoints"></a>

Neptune 叢集的自訂端點代表您選擇的一組資料庫執行個體。連線至端點時，Neptune 會選擇群組的其中一個執行個體來處理連線。您可以定義此端點要參考的執行個體，並且決定端點的運作目的。

Neptune 資料庫叢集沒有自訂端點，直到您建立一個自訂端點，而且您可以為每個佈建的 Neptune 叢集建立最多五個自訂端點。

自訂端點可根據資料庫執行個體的唯讀或讀寫功能以外的準則來提供負載平衡的資料庫連線。由於連線可能前往與端點相關聯的任何資料庫執行個體，因此確定該群組內的所有執行個體分享相同的效能和記憶體容量特性。使用自訂端點時，您一般不會對該叢集使用讀取器端點。

此功能預期供具有專精類型工作負載的進階使用者使用，在其工作負載中，讓叢集中的所有 Neptune 複本保持相同並不切實際。利用自訂端點，您可以調整與每個連線搭配使用的資料庫執行個體容量。

例如，如果您定義數個自訂端點，而這些端點連線到具有不同執行個體類別的執行個體群組，則可以將效能需求不同的使用者導向至最適合其使用案例的端點。

下列範例說明 Neptune 資料庫叢集中資料庫執行個體的自訂端點：

`myendpoint.cluster-custom-123456789012.us-east-1.neptune.amazonaws.com:8182`

如需詳細資訊，請參閱[使用自訂端點](feature-custom-endpoint-membership.md)。

## Neptune 端點考量
<a name="feature-overview-endpoint-considerations"></a>

使用 Neptune 端點時，請考慮下列情況：
+ 使用執行個體端點來連接至資料庫叢集中的特定資料庫執行個體之前，請考慮改為針對資料庫叢集使用叢集端點或讀取器端點。

  叢集端點和讀取器端點提供高可用性案例的支援。如果資料庫叢集的主要資料庫執行個體失敗，Neptune 會自動容錯移轉至新的主要資料庫執行個體。它會透過將現有的 Neptune 複本提升為新的主要資料庫執行個體，或建立新的主要資料庫執行個體來完成。如果發生容錯移轉，您可以使用叢集端點重新連線至新提升或建立的主要資料庫執行個體，或使用讀取器端點重新連線至資料庫叢集中其中一個其他的 Neptune 複本。

  如果您不採取此方法，您仍可以針對預期的操作確定已連接至資料庫叢集中的正確資料庫執行個體。若要這麼做，您可以手動或以程式設計方式探索資料庫叢集中可用資料庫執行個體的結果集，並在容錯移轉之後，於使用特定資料庫執行個體的執行個體端點之前確認其執行個體類型。

  如需容錯移轉的詳細資訊，請參閱 [Neptune 資料庫叢集的容錯能力](backup-restore-overview-fault-tolerance.md)。

   
+ 讀取器端點只會將連線導向 Neptune 資料庫叢集中可用的 Neptune 複本。它不會將特定查詢導向。
**重要**  
Neptune 不會進行負載平衡。

  如果您想要平衡查詢負載以分配資料庫叢集的讀取工作負載，您必須管理您應用程式的負載。您必須使用執行個體端點直接連線到 Neptune 複本，以平衡負載。

   
+ 讀取器端點循環配置資源路由的運作方式是改變 DNS 項目指向的主機。用戶端必須建立新的連線並再次解析 DNS 紀錄，以取得可能是新的僅供讀取複本的連線。

   
+ 在容錯移轉期間，當 Neptune 複本提升為新的主要資料庫執行個體時，讀取器端點可能會短暫直接連線至資料庫叢集的新主要資料庫執行個體。

# 使用 Neptune 中的自訂端點
<a name="feature-custom-endpoint-membership"></a>

新增資料庫執行個體至自訂端點或將它從自訂端點移除時，對該資料庫執行個體的任何現有連線會保持作用中。

您可以定義要包含在自訂端點中的資料庫執行個體清單 (「靜態」**清單)，或定義要從自訂端點中排除的資料庫執行個體清單 (「排除」**清單)。您可以使用包含/排除機制，將資料庫執行個體細分為群組，以及確定自訂端點涵蓋叢集中的所有資料庫執行個體。每個自訂端點只能包含這些清單類型的其中一個。

在 中 AWS 管理主控台，選擇會以核取方塊表示 **連接未來新增至此叢集的執行個體**。將該核取方塊保持未選取時，自訂端點會使用僅包含對話方塊中所指定資料庫執行個體的靜態清單。當您勾選該核取方塊時，自訂端點會使用排除清單。在此情況下，自訂端點會呈現叢集中的所有資料庫執行個體 (包括您未來所新增的任何項目)，在對話方塊中保持未選取的那些除外。

當主要執行個體與 Neptune 複本之間因為容錯移轉或提升，而造成資料庫執行個體變更角色時，Neptune 不會變更靜態或排除清單中指定的資料庫執行個體。

您可以將一個資料庫執行個體與多個自訂端點建立關聯。例如，假設您將新的資料庫執行個體新增至叢集。在這些情況下，資料庫執行個體會新增至符合其資格的所有自訂端點。針對其定義的靜態或排除清單會確定哪個資料庫執行個體可以新增至其中。

如果端點包含資料庫執行個體的靜態清單，新增加的 Neptune 複本不會新增至其中。相反地，如果端點具有排除清單，剛新增的 Neptune 複本會新增至其中，前提是它們未在排除清單中具名。

 如果 Neptune 複本變得無法使用，則會保持與其自訂端點相關聯。無論其是運作狀態不佳、已停止、重新啟動或由於其他原因而無法使用，都是如此。不過，只要它仍然無法使用，您就無法透過任何端點連線至其中。

由於新建立的 Neptune 叢集沒有自訂端點，因此您必須自行建立和管理這些自訂端點。對於從快照還原的 Neptune 叢集也是如此，因為自訂端點未包含在快照中。如果還原的叢集位於與原始叢集相同的區域，則您已在還原之後建立它們，並選擇端點名稱。

## 建立自訂端點
<a name="feature-custom-endpoint-create"></a>

使用 Neptune 主控台管理自訂端點。導覽至 Neptune 叢集的詳細資訊頁面，並使用**自訂端點**區段中的控制項來執行此操作。

1. 登入 AWS 管理主控台，並在 [https://console.aws.amazon.com/neptune/home](https://console.aws.amazon.com/neptune/home)：// 開啟 Amazon Neptune 主控台。

1. 導覽至叢集詳細資訊頁面。

1. 在**端點**區段中選擇 `Create custom endpoint` 動作。

1. 選擇自訂端點的名稱，該名稱是您的使用者 ID 和區域的唯一。名稱長度必須在 63 個字元以內，並採取下列格式：

   `endpointName.cluster-custom-customerDnsIdentifier.dnsSuffix`

   由於自訂端點名稱未包含您的叢集名稱，如果將叢集重新命名，便不需變更這些名稱。不過，您不可以對同一區域中的多個叢集重複使用相同的自訂端點名稱。提供每個自訂端點一個名稱，該名稱在您的使用者 ID 於特定區域內所擁有的叢集間都是唯一的。

1. 若要選取即使在叢集展開時仍保持相同的資料庫執行個體清單，請將核取方塊 **Attach future instances added to this cluster (連線新增至此叢集的未來執行個體)** 保持未選取。勾選該核取方塊時，自訂端點會在任何新的執行個體新增至叢集時動態新增這些執行個體。

## 檢視自訂端點
<a name="feature-custom-endpoints-view"></a>

1. 登入 AWS 管理主控台，並在 [https://console.aws.amazon.com/neptune/home](https://console.aws.amazon.com/neptune/home)：// 開啟 Amazon Neptune 主控台。

1. 導覽至資料庫叢集的叢集詳細資訊頁面。

1. **端點**區段僅包含自訂端點的相關資訊 (有關內建端點的詳細資訊會列示在主要**詳細資訊**區段中)。若要查看特定自訂端點的詳細資訊，請選取其名稱，以帶出該端點的詳細資訊頁面。

## 編輯自訂端點
<a name="feature-custom-endpoint-edit"></a>

您可以編輯自訂端點的屬性，以變更與其相關聯的資料庫執行個體。您也可以在靜態清單與排除清單之間進行切換。

您無法在編輯動作的變更進行中時連線至或使用自訂端點。在端點狀態回到**可用**，且您可以重新連線之前，可能需要幾分鐘的時間。

1. 登入 AWS 管理主控台，並在 [https://console.aws.amazon.com/neptune/home](https://console.aws.amazon.com/neptune/home)：// 開啟 Amazon Neptune 主控台。

1. 導覽至叢集詳細資訊頁面。

1. 在**端點**區段中，選擇您要編輯之自訂端點的名稱。

1. 在該端點的詳細資訊頁面中，選擇**編輯**動作。

## 刪除自訂端點
<a name="feature-custom-endpoint-delete"></a>

1. 登入 AWS 管理主控台，並在 [https://console.aws.amazon.com/neptune/home](https://console.aws.amazon.com/neptune/home)：// 開啟 Amazon Neptune 主控台。

1. 導覽至叢集詳細資訊頁面。

1. 在**端點**區段中，選擇您要刪除之自訂端點的名稱。

1. 在該端點的詳細資訊頁面中，選擇**刪除**動作。

# Neptune 實驗室模式
<a name="features-lab-mode"></a>

您可以使用 Amazon Neptune「實驗室模式」**，以啟用目前 Neptune 引擎版本中的新功能，但這些功能尚未準備好用於生產用途，因此預設為未啟用。這可讓您在開發和測試環境中試用這些功能。

## 使用 Neptune 實驗室模式
<a name="features-lab-mode-using"></a>

使用 [`neptune_lab_mode` 資料庫叢集參數](parameters.md#parameters-db-cluster-parameters-neptune_lab_mode)來啟用或停用功能。做法是在資料庫叢集參數群組的 `neptune_lab_mode` 參數值中包含 `(feature name)=enabled` 或 `(feature name)=disabled`。

例如，在此引擎版本中，您可將 `neptune_lab_mode` 參數設為 `Streams=disabled, ReadWriteConflictDetection=enabled`。

如需如何針對您的資料庫編輯資料庫叢集參數群組的相關資訊，請參閱[編輯參數群組](parameter-groups.md#parameters-editgroup)。請注意，您無法編輯預設資料庫叢集參數群組；如果您是使用預設群組，則必須建立新的資料庫叢集參數群組，才能設定 `neptune_lab_mode` 參數。

**注意**  
當您對靜態資料庫叢集參數 (例如 `neptune_lab_mode`) 進行變更時，必須重新啟動叢集的主要 (寫入器) 執行個體，變更才會生效。在 [版本：1.2.0.0 (2022 年 7 月 21 日)](engine-releases-1.2.0.0.md) 之前，當主要執行個體重新啟動時，資料庫叢集中的所有僅供讀取複本都會自動重新啟動  
從 [版本：1.2.0.0 (2022 年 7 月 21 日)](engine-releases-1.2.0.0.md) 開始，重新啟動主要執行個體並不會導致任何複本重新啟動。這表示您必須個別重新啟動每個執行個體，才能取得資料庫叢集參數變更 (請參閱 [參數群組](parameter-groups.md))。

**重要**  
目前，如果您提供了錯誤的實驗室模式參數，或者您的請求由於其他原因而失敗，則可能不會通知您發生失敗。您應該一律透過呼叫[狀態 API](access-graph-status.md) 來驗證實驗室模式變更請求是否成功，如下所示：  

```
curl -G https://your-neptune-endpoint:port/status
```
狀態結果包括實驗室模式資訊，這些資訊會顯示您請求的變更是否已進行：  

```
{
  "status":"healthy",
  "startTime":"Wed Dec 29 02:29:24 UTC 2021",
  "dbEngineVersion":"development",
  "role":"writer",
  "dfeQueryEngine":"viaQueryHint",
  "gremlin":{"version":"tinkerpop-3.5.2"},
  "sparql":{"version":"sparql-1.1"},
  "opencypher":{"version":"Neptune-9.0.20190305-1.0"},
  "labMode":{
    "ObjectIndex":"disabled",
    "ReadWriteConflictDetection":"enabled"
  },
  "features":{
    "LookupCache":{"status":"Available"},
    "ResultCache":{"status":"disabled"},
    "IAMAuthentication":"disabled",
    "Streams":"disabled",
    "AuditLog":"disabled"
  },
  "settings":{"clusterQueryTimeoutInMs":"120000"}
}
```

目前可使用實驗室模式存取下列功能：

## OSGP 索引
<a name="features-lab-mode-features-osgp-index"></a>

Neptune 現在可以維護第四個索引，即 OSGP 索引，這對於具有大量述詞的資料集很有用 (請參閱 [啟用 OSGP 索引](feature-overview-storage-indexing.md#feature-overview-storage-indexing-osgp))。

您可以在 `neptune_lab_mode` 資料庫叢集參數中設定 `ObjectIndex=enabled`，在新的空白 Neptune 資料庫叢集中啟用 OSGP 索引。OSGP 索引只****能在新的空白資料庫叢集中啟用。

根據預設，停用 OSGP 索引。

**注意**  
在設定 `neptune_lab_mode` 資料庫叢集參數，以便啟用 OSGP 索引之後，您必須重新啟動叢集的寫入器執行個體，變更才會生效。

**警告**  
如果您透過設定 `ObjectIndex=disabled` 來停用已啟用的 OSGP 索引，稍後又在新增更多資料之後重新啟用它，則將無法正確建立索引。不支援隨需重建索引，因此您應該只在資料庫為空時才啟用 OSGP 索引。

## 啟用字典垃圾收集
<a name="features-lab-mode-features-gc"></a>

當 neptune-streams 未透過 `DictionaryGCMode` 參數啟用時，可以為屬性圖形資料啟用字典垃圾收集。並行可以透過 `DictionaryGCConcurrency` 參數控制。如需詳細資訊，請參閱[字典垃圾回收](storage-gc.md)。

## 正規化的交易語意
<a name="features-lab-mode-features-transaction-semantics"></a>

Neptune 已更新並行交易的正式語義 (請參閱 [Neptune 中的交易語意](transactions.md))。

在啟用或停用格式化交易語義的 `neptune_lab_mode` 參數中，使用 `ReadWriteConflictDetection` 做為名稱。

根據預設，已啟用正規化的交易語意。如果您想要還原為先前行為，請將 `ReadWriteConflictDetection=disabled` 併入針對資料庫叢集 `neptune_lab_mode` 參數設定的值中。

## 延長日期時間支援
<a name="labmode-extended-datetime-support"></a>

 Neptune 已擴充對日期時間功能的支援。若要使用擴充格式啟用日期時間，`DatetimeMillisecond=enabled`請在資料庫叢集`neptune_lab_mode`參數的值集中包含 。

## StrictTimeoutValidation
<a name="labmode-StrictTimeoutValidation"></a>

**注意**  
從 [Neptune 引擎版本 1.3.2.0 ](engine-releases-1.3.2.0.md)開始，即可使用此功能。

 預設值：已啟用 （在 [Neptune 引擎版本 1.4.0.0](engine-releases-1.4.0.0.md) 之前預設為停用） 

 允許的值：啟用/停用 

 當此參數為 時`enabled`，指定為請求選項或查詢提示的每個查詢逾時值不能超過[`neptune_query_timeout`](parameters.md#parameters-db-cluster-parameters-neptune_query_timeout)參數群組設定中全域設定的值。如果每個查詢逾時超過全域設定，Neptune 會擲回 `InvalidParameterException`。在 1.4.0.0 之前的引擎版本中，此參數`disabled`預設為預設，且必須明確啟用。

 當值為 時，可以在`/status`端點的回應中確認此設定`disabled`。

 如需詳細資訊，請參閱[每個查詢逾時](best-practices-gremlin-java-per-query-timeout.md)。

## AccurateQRCMemoryEstimation
<a name="labmode-AccurateQRCMemoryEstimation"></a>

**注意**  
從 [Neptune 引擎版本 1.4.0.0 ](engine-releases-1.4.0.0.md)開始，即可使用此功能。

 預設值：停用 

 允許的值：啟用/停用 

 [Gremlin 查詢結果快取](https://docs.aws.amazon.com//neptune/latest/userguide/gremlin-results-cache.html)啟用時，允許在資料庫上快取查詢結果。透過停用，近似值估算用於確定快取結果的大小，啟用此實驗室模式參數時`AccurateQRCMemoryEstimation`，快取結果的大小估算將使用準確的大小估算，而不是近似值。此 實驗室模式參數從 Neptune 引擎版本 1.4.0.0 開始可用。

# Amazon Neptune 替代查詢引擎（DFE）
<a name="neptune-dfe-engine"></a>

Amazon Neptune 具有稱為 DFE 的替代查詢引擎，它比原始 Neptune 引擎更能有效率地使用資料庫執行個體資源 (例如 CPU 核心、記憶體和 I/O)。

**注意**  
使用大型資料集，DFE 引擎可能無法在 t3 執行個體上很好地執行。

DFE 引擎會執行 SPARQL、Gremlin 和 OpenCypher 查詢，並支援廣泛的各種計畫類型，包括 left-deep、bushy 和 hybrid 計畫類型。計畫運算子可以調用在一組保留運算核心上執行的運算操作，也可以調用 I/O 操作，每個操作都會在 I/O 執行緒集區的自己執行緒上執行。

DFE 會使用有關 Neptune 圖形資料的預先產生統計資料，做出有關如何建構查詢的明智決策。如需如何產生這些統計資料的相關資訊，請參閱 [DFE 統計資料](neptune-dfe-statistics.md)。

系統會根據預先產生的統計資料和 Neptune 前端節點中可用的資源，自動選擇計畫類型和己使用的運算執行緒數目。結果的順序不是針對具有內部運算平行處理的計畫預先確定的。

# 控制 Neptune DFE 引擎的使用位置
<a name="neptune-dfe-enabling-disabling"></a>

根據預設，執行個體的 [neptune\$1dfe\$1query\$1engine](parameters.md#parameters-instance-parameters-neptune_dfe_query_engine) 執行個體參數會設定為 `viaQueryHint`，這會導致 DFE 引擎僅用於 OpenCypher 查詢，以及明確包含 `useDFE` 查詢提示 (設定為 `true`) 的 Gemlin 和 SPARQL 查詢。

您可以透過將 `neptune_dfe_query_engine` 執行個體參數設定為 `enabled` 來完全啟用 DFE 引擎，以便盡可能使用該引擎。

您也可以透過包含特定 [Gremlin 查詢](gremlin-query-hints-useDFE.md)或 [SPARQL 查詢](sparql-query-hints-useDFE.md)的 `useDFE` 查詢提示來停用 DFE。此查詢提示可讓您防止 DFE 執行該特定查詢。

您可以使用如下的 [執行個體狀態](access-graph-status.md) 呼叫，判斷是否在執行個體中已啟用 DFE：

```
curl -G https://your-neptune-endpoint:port/status
```

然后，狀態回應會指定是否已啟用 DFE：

```
{
  "status":"healthy",
  "startTime":"Wed Dec 29 02:29:24 UTC 2021",
  "dbEngineVersion":"development",
  "role":"writer",
  "dfeQueryEngine":"viaQueryHint",
  "gremlin":{"version":"tinkerpop-3.5.2"},
  "sparql":{"version":"sparql-1.1"},
  "opencypher":{"version":"Neptune-9.0.20190305-1.0"},
  "labMode":{
    "ObjectIndex":"disabled",
    "ReadWriteConflictDetection":"enabled"
  },
  "features":{
    "ResultCache":{"status":"disabled"},
    "IAMAuthentication":"disabled",
    "Streams":"disabled",
    "AuditLog":"disabled"
  },
  "settings":{"clusterQueryTimeoutInMs":"120000"}
}
```

Grimlin `explain` 和 `profile` 結果會告訴您 DFE 是否正在執行查詢。請參閱 [Gremlin `explain` 報告中包含的資訊](gremlin-explain-api.md#gremlin-explain-api-results) (若為 `explain`) 和 [DFE `profile` 報告](gremlin-profile-api.md#gremlin-profile-dfe-output) (若為 `profile`)。

同樣地，SPARQL `explain` 會告訴您 DFE 是否正在執行 SPARQL 查詢。如需詳細資訊，請參閱 [DFE 啟用時的 SPARQL `explain` 輸出範例](sparql-explain-examples.md#sparql-explain-output-dfe) 和 [`DFENode`運算子](sparql-explain-operators.md#sparql-explain-operator-dfenode)。

# Neptune DFE 支援的查詢建構模組
<a name="neptune-dfe-suppoorts-subset"></a>

目前，Neptune DFE 支援 SPARQL 和 Gremlin 查詢建構模組的子集。

對於 SPARQL，這是結合的[基本圖形模式](https://www.w3.org/TR/sparql11-query/#BasicGraphPatterns)子集。

對於 Gemlin，它通常是查詢的子集，而這些查詢包含的周遊鏈未包含一些更複雜的步驟。

您可以找出 DFE 是全部還是部分執行您的其中一個查詢，如下所示：
+ 在 Gremlin 中，`explain` 和 `profile` 結果會告訴您 DFE 正在執行查詢的哪些部分 (如果有的話)。請參閱 [Gremlin `explain` 報告中包含的資訊](gremlin-explain-api.md#gremlin-explain-api-results) (若為 `explain`) 和 [DFE `profile` 報告](gremlin-profile-api.md#gremlin-profile-dfe-output) (若為 `profile`)。另請參閱 [使用 `explain` 和 `profile` 調校 Gremlin 查詢](gremlin-traversal-tuning.md)。

  有關 Neptune 引擎對個別 Gemlin 步驟之支援的詳細資訊，記載於 [Gremlin 步驟支援](gremlin-step-support.md) 中。
+ 同樣地，SPARQL `explain` 會告訴您 DFE 是否正在執行 SPARQL 查詢。如需詳細資訊，請參閱 [DFE 啟用時的 SPARQL `explain` 輸出範例](sparql-explain-examples.md#sparql-explain-output-dfe) 和 [`DFENode`運算子](sparql-explain-operators.md#sparql-explain-operator-dfenode)。

# 管理要供 Neptune DFE 使用的統計資料
<a name="neptune-dfe-statistics"></a>

**注意**  
對 openCypher 的支援取決於 Neptune 中的 DFE 查詢引擎。  
DFE 引擎首先在 [Neptune 引擎 1.0.3.0 版](engine-releases-1.0.3.0.md)的實驗室模式中使用，而且從 [Neptune 引擎 1.0.5.0 版](engine-releases-1.0.5.0.md)開始，預設為啟用，但僅能與查詢提示搭配使用，以及僅適用於 OpenCypher 支援。  
從 [Neptune 引擎 1.1.1.0 版](engine-releases-1.1.1.0.md)開始，DFE 引擎不再處於實驗室模式，而且現在可以使用執行個體資料庫參數群組中的 [neptune\$1dfe\$1query\$1engine](parameters.md#parameters-instance-parameters-neptune_dfe_query_engine) 執行個體參數來控制此引擎。

DFE 引擎會在規劃查詢執行時，使用 Neptune 圖形中的資料相關資訊，進行有效的權衡。這項資訊採取統計資料的形式，其中包括所謂的特性集和述詞統計資料，可以引導查詢規劃。

從[引擎 1.2.1.0 版](engine-releases-1.2.1.0.md)開始，您可以使用 [GetGraphSummary](iam-dp-actions.md#getgraphsummary) API 或 `summary` 端點，從這些統計資料中擷取有關圖形的[摘要資訊](neptune-graph-summary.md)。

目前，每當圖形中超過 10% 的資料已變更或最新統計資料已過了 10 天時，就會重新產生這些 DFE 統計資料。不過，這些觸發條件日後可能會變更。

**注意**  
統計資料產生會在 `T3` 和 `T4g` 執行個體上停用，因為它可能超過這些執行個體類型的記憶體容量。

您可以透過下列其中一個端點管理 DFE 統計資料的產生：
+ `https://your-neptune-host:port/rdf/statistics ` (適用於 SPARQL)。
+ `https://your-neptune-host:port/propertygraph/statistics` (適用於 Gremlin 和 openCypher)，以及它的替代版本：`https://your-neptune-host:port/pg/statistics`。

**注意**  
從[引擎 1.1.1.0 版](engine-releases-1.1.1.0.md)開始，Gramlin 統計資料端點 (`https://your-neptune-host:port/gremlin/statistics`) 已被棄用以支持 `propertygraph` 或 `pg` 端點。基於回溯相容性仍支援它，但可能會在未來的版本中將其移除。  
從[引擎 1.2.1.0 版](engine-releases-1.2.1.0.md)開始，SPARQL 統計資料端點 (`https://your-neptune-host:port/sparql/statistics`) 已被棄用以支持 `rdf` 端點。基於回溯相容性仍支援它，但可能會在未來的版本中將其移除。

在下面範例中，`$STATISTICS_ENDPOINT` 代表這些端點 URL 中的任何一個。

**注意**  
如果 DFE 統計資料端點位於讀取器執行個體上，則它可以處理的唯一請求是[狀態請求](#neptune-dfe-statistics-status)。其他請求將由於 `ReadOnlyViolationException` 而失敗。

## 對 DFE 統計資料產生的大小限制
<a name="neptune-dfe-statistics-limits"></a>

目前，如果達到下列任一大小限制，DFE 統計資料產生便會中止：
+ 所產生的特性集數目不得超過 50,000 個。
+ 所產生的述詞統計資料數目不得超過一百萬個。

這些限制可能會變更。

## DEF 統計資枓的目前狀態。
<a name="neptune-dfe-statistics-status"></a>

您可使用下列 `curl` 請求檢查 DFE 統計資料的目前狀態：

```
curl -G "$STATISTICS_ENDPOINT"
```

對狀態請求的回應包含下列欄位：
+ `status` – 請求的 HTTP 傳回碼。如果請求成功，則傳回碼為 `200`。如需常見錯誤的清單，請參閱 [常見錯誤](#neptune-dfe-statistics-errors)。
+ `payload`:
  + `autoCompute` – (布林值) 指示是否啟用自動產生統計資料。
  + `active` – (布林值) 指示是否完全啟用 DFE 統計資料產生。
  + `statisticsId ` – 報告目前統計資料產生執行的 ID。值 ` -1 ` 指示尚未產生任何統計資料。
  + `date` – 最近產生 DFE 統計資料的 UTC 時間，以 ISO 8601 格式表示。
**注意**  
在[引擎 1.2.1.0 版](engine-releases-1.2.1.0.md)之前，這是以分鐘精確度表示，但從引擎 1.2.1.0 版開始，它是以毫秒精確度表示 (例如，`2023-01-24T00:47:43.319Z`)。
  + `note` – 關於統計資料無效情況下問題的說明。
  + `signatureInfo` – 包含統計資料中所產生之特性集的相關資訊 (在[引擎 1.2.1.0 版](engine-releases-1.2.1.0.md)之前，此欄位已命名為 `summary`)。這些通常不能直接採取行動：
    + `signatureCount` – 所有特性集的簽章總數。
    + `instanceCount` – 特性集執行個體的總數。
    + `predicateCount` – 唯一述詞的總數。

未產生統計資料時，對狀態請求的回應如下所示：

```
{
  "status" : "200 OK",
  "payload" : {
    "autoCompute" : true,
    "active" : false,
    "statisticsId" : -1
   }
}
```

如果 DFE 統計資料可用，回應如下所示：

```
{
  "status" : "200 OK",
  "payload" : {
    "autoCompute" : true,
    "active" : true,
    "statisticsId" : 1588893232718,
    "date" : "2020-05-07T23:13Z",
    "summary" : {
      "signatureCount" : 5,
      "instanceCount" : 1000,
      "predicateCount" : 20
    }
  }
}
```

如果 DFE 統計資料產生失敗，例如因為其超出[統計資料大小限制](#neptune-dfe-statistics-limits)，回應如下所示：

```
{
  "status" : "200 OK",
  "payload" : {
    "autoCompute" : true,
    "active" : false,
    "statisticsId" : 1588713528304,
    "date" : "2020-05-05T21:18Z",
    "note" : "Limit reached: Statistics are not available"
  }
}
```

## 停用自動產生 DFE 統計資料
<a name="neptune-dfe-statistics-auto-disable"></a>

根據預設，啟用 DFE 時，會啟用自動產生 DFE 統計資料。

您可以停用自動產生，如下所示：

```
curl -X POST "$STATISTICS_ENDPOINT" -d '{ "mode" : "disableAutoCompute" }'
```

如果請求成功，HTTP 回應代碼為 `200`，且回應為：

```
{
  "status" : "200 OK"
}
```

您可以發出[狀態請求](#neptune-dfe-statistics-status)並檢查回應中的 `autoCompute` 欄位是否設定為 `false`，以確認已停用自動產生。

停用自動產生統計資料並不會終止進行中的統計資料計算。

如果您提出請求，停用讀取器執行個體的自動產生，而不是資料庫叢集的寫入器執行個體的自動產生，則請求會失敗，HTTP 傳回碼為 400，且輸出如下所示：

```
{
  "detailedMessage" : "Writes are not permitted on a read replica instance",
  "code" : "ReadOnlyViolationException",
  "requestId":"8eb8d3e5-0996-4a1b-616a-74e0ec32d5f7"
}
```

如需其他常見錯誤的清單，請參閱 [常見錯誤](#neptune-dfe-statistics-errors)。

## 重新啟用自動產生 DFE 統計資料
<a name="neptune-dfe-statistics-auto-re-enable"></a>

根據預設，啟用 DFE 時，已啟用自動產生 DFE 統計資料。如果您停用自動產生，您可以稍後重新啟用它，如下所示：

```
curl -X POST "$STATISTICS_ENDPOINT" -d '{ "mode" : "enableAutoCompute" }'
```

如果請求成功，HTTP 回應代碼為 `200`，且回應為：

```
{
  "status" : "200 OK"
}
```

您可以發出[狀態請求](#neptune-dfe-statistics-status)並檢查回應中的 `autoCompute` 欄位是否設定為 `true`，以確認已啟用自動產生。

## 手動觸發 DFE 統計資料的產生
<a name="neptune-dfe-statistics-manual"></a>

您可以手動啟動 DFE 統計資料產生，如下所示：

```
curl -X POST "$STATISTICS_ENDPOINT" -d '{ "mode" : "refresh" }'
```

如果請求成功，則輸出如下，HTTP 傳回碼為 200：

```
{
  "status" : "200 OK",
  "payload" : {
    "statisticsId" : 1588893232718
  }
}
```

輸出中的 `statisticsId` 是目前正在發生之統計資料產生執行的識別符。如果執行已在請求時已處理中，則請求會傳回該執行的 ID，而不是啟動新的 ID。一次僅能發生一個統計資料產生執行。

如果在產生 DFE 統計資料時發生容錯移轉，新的寫入器節點會取得上次處理的檢查點，並從該處繼續統計資料執行。

## 使用 `StatsNumStatementsScanned` CloudWatch 指標監控統計資料計算
<a name="neptune-dfe-statistics-monitoring"></a>

`StatsNumStatementsScanned` CloudWatch 指標會傳回自伺服器啟動以來針對統計資料計算掃描的陳述式總數。它是在每個統計資料計算部分處更新。

每次觸發統計資料計算時，這個數字都會增加，並且當沒有計算發生時，它會保持不變。因此，查看隨時間變化的 `StatsNumStatementsScanned` 值圖，可以很清楚地了解統計資料計算何時發生以及有多快：

![\[StatsNumStatementsScanned 指標值的圖形\]](http://docs.aws.amazon.com/zh_tw/neptune/latest/userguide/images/StatsNumStatementsScanned-graph.png)


進行計算時，圖形的斜坡會向您顯示有多快 (斜坡越陡，統計資料的計算速度越快)。

如果圖形只是一條位於 0 的平直線，表示已啟用統計資料功能，但根本沒有計算任何統計資料。如果已停用統計資料功能，或者如果您使用的引擎版本不支援統計資料計算，則 `StatsNumStatementsScanned` 不存在。

如先前所述，您可以使用統計資料 API 停用統計資料計算，但是將其保留關閉狀態可能會導致統計資料不是最新的，進而導致針對 DFE 引擎產生不良的查詢計畫。

如需如何使用 CloudWatch 的相關資訊，請參閱 [使用 Amazon CloudWatch 監控 Neptune](cloudwatch.md)。

## 搭配 DFE 統計資料端點使用 AWS Identity and Access Management (IAM) 身分驗證
<a name="neptune-dfe-statistics-iam-auth"></a>

您可以使用 [awscurl](https://github.com/okigan/awscurl) 或任何使用 HTTPS 和 IAM 的任何工具，搭配 IAM 身分驗證安全地存取 DFE 統計資料端點。請參閱 [使用 `awscurl` 搭配臨時憑證，安全地連線至啟用 IAM 身分驗證的資料庫叢集](iam-auth-connect-command-line.md#iam-auth-connect-awscurl) 以了解如何設定適當的憑證。一旦完成了該操作，您就可以提出如下的狀態請求：

```
awscurl "$STATISTICS_ENDPOINT" \
    --region (your region) \
    --service neptune-db
```

或者，您可以建立名為 `request.json` 的 JSON 檔案，其中包含：

```
{ "mode" : "refresh" }
```

您可以接著手動啟動統計資料產生，如下所示：

```
awscurl "$STATISTICS_ENDPOINT" \
    --region (your region) \
    --service neptune-db \
    -X POST -d @request.json
```

## 刪除 DEF 統計資料
<a name="neptune-dfe-statistics-delete"></a>

您可以對統計資料端點發出 HTTP DELETE 請求，來刪除資料庫中的所有統計資料：

```
curl -X "DELETE" "$STATISTICS_ENDPOINT"
```

有效的 HTTP 傳回碼為：
+ `200` – 刪除成功。

  在此情況下，典型的回應如下所示：

  ```
  {
    "status" : "200 OK",
    "payload" : {
        "active" : false,
        "statisticsId" : -1
    }
  }
  ```
+ `204` – 沒有任何要刪除的統計資料。

  在此情況下，回應是空白的 (沒有回應)。

如果將刪除請求傳送至讀取器節點上的統計資料端點，則會擲回 `ReadOnlyViolationException`。

## DFE 統計資料請求的常見錯誤代碼
<a name="neptune-dfe-statistics-errors"></a>

以下是當您對統計資料端點提出請求時可能發生的常見錯誤清單：
+ `AccessDeniedException` – *傳回碼：*`400`。*訊息：*`Missing Authentication Token`。
+ `BadRequestException` (適用於 Gremlin 和 openCypher) – *傳回碼：*`400`。*訊息：*`Bad route: /pg/statistics`。
+ `BadRequestException` (適用於 RDF 資料) – *傳回碼：*`400`。*訊息：*`Bad route: /rdf/statistics`。
+ `InvalidParameterException` – *傳回碼：*`400`。*訊息：*`Statistics command parameter 'mode' has unsupported value 'the invalid value'`。
+ `MissingParameterException` – *傳回碼：*`400`。*訊息：*`Content-type header not specified.`。
+ `ReadOnlyViolationException` – *傳回碼：*`400`。*訊息：*`Writes are not permitted on a read replica instance`。

例如，如果您在未啟用 DFE 和統計資料時提出請求，您會得到如下的回應：

```
{
  "code" : "BadRequestException",
  "requestId" : "b2b8f8ee-18f1-e164-49ea-836381a3e174",
  "detailedMessage" : "Bad route: /sparql/statistics"
}
```

# 取得有關圖形的快速摘要報告
<a name="neptune-graph-summary"></a>

Neptune 圖形摘要 API 會擷取圖形的下列相關資訊：
+ 對於屬形 (PG) 圖，圖形摘要 API 會傳回節點和邊緣標籤以及屬性索引鍵的唯讀清單，也會傳回節點、邊緣和屬性的計數。
+ 對於資源描述架構 (RDF) 圖形，圖形摘要 API 會傳回類別和述詞索引鍵的唯讀清單，也會傳回四元組、主旨和述詞的計數。

**注意**  
圖形摘要 API 是在 Neptune [引擎 1.2.1.0 版](engine-releases-1.2.1.0.md)中引進的。

使用圖形摘要 API，您可以快速了解圖形資料大小和內容。您也可以使用 [`%summary`](notebooks-magics.md#notebooks-line-magics-summary) Neptune 工作台魔法，在 Neptune 筆記本內以互動方式使用 API。在圖形應用程式中，API 可以用來改善搜尋結果，方法是提供探索到的節點或邊緣標籤做為搜尋的一部分。

圖形摘要資料取自 [Neptune DFE 引擎](neptune-dfe-engine.md)在執行期所計算的 [DFE 統計資料](neptune-dfe-statistics.md)，而且每當 DFE 統計資料可用時，就可以使用此圖形摘要資料。當您建立新的 Neptune 資料庫叢集時，預設會啟用統計資料。

**注意**  
`t3` 和 `t4` 執行個體類型 (也就是，`db.t3.medium` 和 `db.t4g.medium` 執行個體類型) 上會停用產生統計資料，以節省記憶體。因此，這些執行個體類型上都無法使用圖形摘要資料。

您可以使用[統計資料狀態 API](neptune-dfe-statistics.md#neptune-dfe-statistics-status) 檢查 DFE 統計資料的狀態。只要未[停用](neptune-dfe-statistics.md#neptune-dfe-statistics-auto-disable)自動產生統計資料，就會定期自動更新統計資料。

如果您想要在請求圖形摘要時確定統計資料盡可能是最新的，則可以在擷取摘要之前，[手動觸發統計資料更新](neptune-dfe-statistics.md#neptune-dfe-statistics-manual)。如果圖形在統計資料計算時變更，則它們一定會稍微落後，但不會太多。

## 使用圖形摘要 API 擷取圖形摘要資訊
<a name="neptune-graph-summary-retrieving"></a>

對於您使用 Gremlin 或 OpenCypher 查詢的屬性圖形，您可以從屬性圖摘要端點擷取圖形摘要。此端點既有長 URI 也有短 URI：
+ `https://your-neptune-host:port/propertygraph/statistics/summary`
+ `https://your-neptune-host:port/pg/statistics/summary`

對於您使用 SPARQL 查詢的 RDF 圖形，您可以從 RDF 摘要端點擷取圖形摘要：
+ `https://your-neptune-host:port/rdf/statistics/summary`

這些端點是唯讀端點，且僅支援 HTTP `GET` 操作。如果 \$1GRAPH\$1SUMMARY\$1ENDPOINT 設定為您要查詢之任何端點的地址，則您可以使用 `curl` 和 HTTP `GET` 擷取摘要資料，如下所示：

```
curl -G "$GRAPH_SUMMARY_ENDPOINT"
```

如果在嘗試擷取圖形摘要時沒有可用的統計資料，則回應如下所示：

```
{
  "detailedMessage": "Statistics are not available. Summary can only be generated after statistics are available.",
  "requestId": "48c1f788-f80b-b69c-d728-3f6df579a5f6",
  "code": "StatisticsNotAvailableException"
}
```

## 圖形摘要 API 的 `mode` URL 查詢參數
<a name="neptune-graph-summary-mode"></a>

圖形摘要 API 接受名為 `mode` 的 URL 查詢參數，該參數可以採取兩個值之一，即 `basic` (預設值) 和 `detailed`。對於 RDF 圖，`detailed` 模式圖形摘要回應包含一個額外的 `subjectStructures` 欄位。對於屬性圖，詳細的圖形摘要回應包含兩個額外的欄位，即 `nodeStructures` 和 `edgeStructures`。

若要請求 `detailed` 圖形摘要回應，請包含 `mode` 參數，如下所示：

```
curl -G "$GRAPH_SUMMARY_ENDPOINT?mode=detailed"
```

如果 `mode` 參數不存在，則預設會使用 `basic` 模式，因此儘管可以明確指定 `?mode=basic`，但這不是必需的。

## 屬性圖 (PG) 的圖形摘要回應
<a name="neptune-graph-summary-pg-response"></a>

對於空的屬性圖，詳細的圖形摘要回應如下所示：

```
{
  "status" : "200 OK",
  "payload" : {
    "version" : "v1",
    "lastStatisticsComputationTime" : "2023-01-10T07:58:47.972Z",
    "graphSummary" : {
      "numNodes" : 0,
      "numEdges" : 0,
      "numNodeLabels" : 0,
      "numEdgeLabels" : 0,
      "nodeLabels" : [ ],
      "edgeLabels" : [ ],
      "numNodeProperties" : 0,
      "numEdgeProperties" : 0,
      "nodeProperties" : [ ],
      "edgeProperties" : [ ],
      "totalNodePropertyValues" : 0,
      "totalEdgePropertyValues" : 0,
      "nodeStructures" : [ ],
      "edgeStructures" : [ ]
    }
  }
}
```

屬性圖 (PG) 摘要回應具有下列欄位：
+ **`status`** – 請求的 HTTP 傳回碼。如果請求成功，則傳回碼為 200。

  如需常見錯誤的清單，請參閱 [常見的圖形摘要錯誤](#neptune-graph-summary-errors)。
+ **`payload`**
  + **`version`** – 此圖形摘要回應的版本。
  + **`lastStatisticsComputationTime `** – Neptune 上次計算[統計資料](neptune-dfe-statistics.md)之時間的時間戳記 (採用 ISO 8601 格式)。
  + **`graphSummary`**
    + **`numNodes`** – 圖形中節點的數目。
    + **`numEdges`** – 圖形中邊緣的數目。
    + **`numNodeLabels`** – 圖形中不同節點標籤的數目。
    + **`numEdgeLabels`** – 圖形中不同邊緣標籤的數目。
    + **`nodeLabels`** – 圖形中不同節點標籤的清單。
    + **`edgeLabels`** – 圖形中不同邊緣標籤的清單。
    + **`numNodeProperties`** – 圖形中不同節點屬性的數目。
    + **`numEdgeProperties`** – 圖形中不同邊緣屬性的數目。
    + **`nodeProperties`** – 圖形中不同節點屬性的清單，以及其中使用每個屬性的節點計數。
    + **`edgeProperties`** – 圖形中不同邊緣屬性的清單，以及其中使用每個屬性的邊緣計數。
    + **`totalNodePropertyValues`** – 所有節點屬性的使用總數。
    + **`totalEdgePropertyValues`** – 所有邊緣屬性的使用總數。
    + **`nodeStructures`** – *只有在請求中指定 `mode=detailed` 時，才會顯示此欄位。*它包含節點結構的清單，每個結構都包含下列欄位：
      + **`count`** – 具有此特定結構的節點數目。
      + **`nodeProperties`** – 此特定結構中存在之節點屬性的清單。
      + **`distinctOutgoingEdgeLabels`** – 此特定結構中存在之不同傳出邊緣標籤的清單。
    + **`edgeStructures`** – *只有在請求中指定 `mode=detailed` 時，才會顯示此欄位。*它包含邊緣結構的清單，每個結構都包含下列欄位：
      + **`count`** – 具有此特定結構的邊緣數目。
      + **`edgeProperties`** – 此特定結構中存在之邊緣屬性的清單。

## RDF 圖形的圖形摘要回應
<a name="neptune-graph-summary-rdf-response"></a>

對於空的 RDF 圖形，詳細的圖形摘要回應如下所示：

```
{
  "status" : "200 OK",
  "payload" : {
    "version" : "v1",
    "lastStatisticsComputationTime" : "2023-01-10T07:58:47.972Z",
    "graphSummary" : {
      "numDistinctSubjects" : 0,
      "numDistinctPredicates" : 0,
      "numQuads" : 0,
      "numClasses" : 0,
      "classes" : [ ],
      "predicates" : [ ],
      "subjectStructures" : [ ]
    }
  }
}
```

RDF 圖形摘要回應具有下列欄位：
+ **`status`** – 請求的 HTTP 傳回碼。如果請求成功，則傳回碼為 200。

  如需常見錯誤的清單，請參閱 [常見的圖形摘要錯誤](#neptune-graph-summary-errors)。
+ **`payload`**
  + **`version`** – 此圖形摘要回應的版本。
  + **`lastStatisticsComputationTime `** – Neptune 上次計算[統計資料](neptune-dfe-statistics.md)之時間的時間戳記 (採用 ISO 8601 格式)。
  + **`graphSummary`**
    + **`numDistinctSubjects`** – 圖形中不同主旨的數目。
    + **`numDistinctPredicates`** – 圖形中不同述詞的數目。
    + **`numQuads`** – 圖形中四元組的數目。
    + **`numClasses`** – 圖形中類別的數目。
    + **`classes`** – 圖形中類別的清單。
    + **`predicates`** – 圖形中述詞的清單，以及述詞計數。
    + **`subjectStructures`** – *只有在請求中指定 `mode=detailed` 時，才會顯示此欄位。*它包含主旨結構的清單，每個結構都包含下列欄位：
      + **`count`** – 此特定結構的出現次數。
      + **`predicates`** – 此特定結構中存在之述詞的清單。

## 範例屬性圖 (PG) 摘要回應
<a name="neptune-graph-summary-sample-pg-response"></a>

以下是屬性圖的詳細摘要回應，其中包含[範例屬性圖航線資料集](https://github.com/aws/graph-notebook/tree/main/src/graph_notebook/seed/queries/propertygraph/gremlin/airports)：

```
{
  "status" : "200 OK",
  "payload" : {
    "version" : "v1",
    "lastStatisticsComputationTime" : "2023-03-01T14:35:03.804Z",
    "graphSummary" : {
      "numNodes" : 3748,
      "numEdges" : 51300,
      "numNodeLabels" : 4,
      "numEdgeLabels" : 2,
      "nodeLabels" : [
        "continent",
        "country",
        "version",
        "airport"
      ],
      "edgeLabels" : [
        "contains",
        "route"
      ],
      "numNodeProperties" : 14,
      "numEdgeProperties" : 1,
      "nodeProperties" : [
        {
          "desc" : 3748
        },
        {
          "code" : 3748
        },
        {
          "type" : 3748
        },
        {
          "country" : 3503
        },
        {
          "longest" : 3503
        },
        {
          "city" : 3503
        },
        {
          "lon" : 3503
        },
        {
          "elev" : 3503
        },
        {
          "icao" : 3503
        },
        {
          "region" : 3503
        },
        {
          "runways" : 3503
        },
        {
          "lat" : 3503
        },
        {
          "date" : 1
        },
        {
          "author" : 1
        }
      ],
      "edgeProperties" : [
        {
          "dist" : 50532
        }
      ],
      "totalNodePropertyValues" : 42773,
      "totalEdgePropertyValues" : 50532,
      "nodeStructures" : [
        {
          "count" : 3471,
          "nodeProperties" : [
            "city",
            "code",
            "country",
            "desc",
            "elev",
            "icao",
            "lat",
            "lon",
            "longest",
            "region",
            "runways",
            "type"
          ],
          "distinctOutgoingEdgeLabels" : [
            "route"
          ]
        },
        {
          "count" : 161,
          "nodeProperties" : [
            "code",
            "desc",
            "type"
          ],
          "distinctOutgoingEdgeLabels" : [
            "contains"
          ]
        },
        {
          "count" : 83,
          "nodeProperties" : [
            "code",
            "desc",
            "type"
          ],
          "distinctOutgoingEdgeLabels" : [ ]
        },
        {
          "count" : 32,
          "nodeProperties" : [
            "city",
            "code",
            "country",
            "desc",
            "elev",
            "icao",
            "lat",
            "lon",
            "longest",
            "region",
            "runways",
            "type"
          ],
          "distinctOutgoingEdgeLabels" : [ ]
        },
        {
          "count" : 1,
          "nodeProperties" : [
            "author",
            "code",
            "date",
            "desc",
            "type"
          ],
          "distinctOutgoingEdgeLabels" : [ ]
        }
      ],
      "edgeStructures" : [
        {
          "count" : 50532,
          "edgeProperties" : [
            "dist"
          ]
        }
      ]
    }
  }
}
```

## 範例 RDF 圖形摘要回應
<a name="neptune-graph-summary-sample-rdf-response"></a>

以下是 RDF 圖形的詳細摘要回應，其中包含[範例 RDF 航線資料集](https://github.com/aws/graph-notebook/tree/main/src/graph_notebook/seed/queries/rdf/sparql/airports)：

```
{
  "status" : "200 OK",
  "payload" : {
    "version" : "v1",
    "lastStatisticsComputationTime" : "2023-03-01T14:54:13.903Z",
    "graphSummary" : {
      "numDistinctSubjects" : 54403,
      "numDistinctPredicates" : 19,
      "numQuads" : 158571,
      "numClasses" : 4,
      "classes" : [
        "http://kelvinlawrence.net/air-routes/class/Version",
        "http://kelvinlawrence.net/air-routes/class/Airport",
        "http://kelvinlawrence.net/air-routes/class/Continent",
        "http://kelvinlawrence.net/air-routes/class/Country"
      ],
      "predicates" : [
        {
          "http://kelvinlawrence.net/air-routes/objectProperty/route" : 50656
        },
        {
          "http://kelvinlawrence.net/air-routes/datatypeProperty/dist" : 50656
        },
        {
          "http://kelvinlawrence.net/air-routes/objectProperty/contains" : 7004
        },
        {
          "http://kelvinlawrence.net/air-routes/datatypeProperty/code" : 3747
        },
        {
          "http://www.w3.org/2000/01/rdf-schema#label" : 3747
        },
        {
          "http://kelvinlawrence.net/air-routes/datatypeProperty/type" : 3747
        },
        {
          "http://kelvinlawrence.net/air-routes/datatypeProperty/desc" : 3747
        },
        {
          "http://www.w3.org/1999/02/22-rdf-syntax-ns#type" : 3747
        },
        {
          "http://kelvinlawrence.net/air-routes/datatypeProperty/icao" : 3502
        },
        {
          "http://kelvinlawrence.net/air-routes/datatypeProperty/lat" : 3502
        },
        {
          "http://kelvinlawrence.net/air-routes/datatypeProperty/region" : 3502
        },
        {
          "http://kelvinlawrence.net/air-routes/datatypeProperty/runways" : 3502
        },
        {
          "http://kelvinlawrence.net/air-routes/datatypeProperty/longest" : 3502
        },
        {
          "http://kelvinlawrence.net/air-routes/datatypeProperty/elev" : 3502
        },
        {
          "http://kelvinlawrence.net/air-routes/datatypeProperty/lon" : 3502
        },
        {
          "http://kelvinlawrence.net/air-routes/datatypeProperty/country" : 3502
        },
        {
          "http://kelvinlawrence.net/air-routes/datatypeProperty/city" : 3502
        },
        {
          "http://kelvinlawrence.net/air-routes/datatypeProperty/author" : 1
        },
        {
          "http://kelvinlawrence.net/air-routes/datatypeProperty/date" : 1
        }
      ],
      "subjectStructures" : [
        {
          "count" : 50656,
          "predicates" : [
            "http://kelvinlawrence.net/air-routes/datatypeProperty/dist"
          ]
        },
        {
          "count" : 3471,
          "predicates" : [
            "http://kelvinlawrence.net/air-routes/datatypeProperty/city",
            "http://kelvinlawrence.net/air-routes/datatypeProperty/code",
            "http://kelvinlawrence.net/air-routes/datatypeProperty/country",
            "http://kelvinlawrence.net/air-routes/datatypeProperty/desc",
            "http://kelvinlawrence.net/air-routes/datatypeProperty/elev",
            "http://kelvinlawrence.net/air-routes/datatypeProperty/icao",
            "http://kelvinlawrence.net/air-routes/datatypeProperty/lat",
            "http://kelvinlawrence.net/air-routes/datatypeProperty/lon",
            "http://kelvinlawrence.net/air-routes/datatypeProperty/longest",
            "http://kelvinlawrence.net/air-routes/datatypeProperty/region",
            "http://kelvinlawrence.net/air-routes/datatypeProperty/runways",
            "http://kelvinlawrence.net/air-routes/datatypeProperty/type",
            "http://kelvinlawrence.net/air-routes/objectProperty/route",
            "http://www.w3.org/1999/02/22-rdf-syntax-ns#type",
            "http://www.w3.org/2000/01/rdf-schema#label"
          ]
        },
        {
          "count" : 238,
          "predicates" : [
            "http://kelvinlawrence.net/air-routes/datatypeProperty/code",
            "http://kelvinlawrence.net/air-routes/datatypeProperty/desc",
            "http://kelvinlawrence.net/air-routes/datatypeProperty/type",
            "http://kelvinlawrence.net/air-routes/objectProperty/contains",
            "http://www.w3.org/1999/02/22-rdf-syntax-ns#type",
            "http://www.w3.org/2000/01/rdf-schema#label"
          ]
        },
        {
          "count" : 31,
          "predicates" : [
            "http://kelvinlawrence.net/air-routes/datatypeProperty/city",
            "http://kelvinlawrence.net/air-routes/datatypeProperty/code",
            "http://kelvinlawrence.net/air-routes/datatypeProperty/country",
            "http://kelvinlawrence.net/air-routes/datatypeProperty/desc",
            "http://kelvinlawrence.net/air-routes/datatypeProperty/elev",
            "http://kelvinlawrence.net/air-routes/datatypeProperty/icao",
            "http://kelvinlawrence.net/air-routes/datatypeProperty/lat",
            "http://kelvinlawrence.net/air-routes/datatypeProperty/lon",
            "http://kelvinlawrence.net/air-routes/datatypeProperty/longest",
            "http://kelvinlawrence.net/air-routes/datatypeProperty/region",
            "http://kelvinlawrence.net/air-routes/datatypeProperty/runways",
            "http://kelvinlawrence.net/air-routes/datatypeProperty/type",
            "http://www.w3.org/1999/02/22-rdf-syntax-ns#type",
            "http://www.w3.org/2000/01/rdf-schema#label"
          ]
        },
        {
          "count" : 6,
          "predicates" : [
            "http://kelvinlawrence.net/air-routes/datatypeProperty/code",
            "http://kelvinlawrence.net/air-routes/datatypeProperty/desc",
            "http://kelvinlawrence.net/air-routes/datatypeProperty/type",
            "http://www.w3.org/1999/02/22-rdf-syntax-ns#type",
            "http://www.w3.org/2000/01/rdf-schema#label"
          ]
        },
        {
          "count" : 1,
          "predicates" : [
            "http://kelvinlawrence.net/air-routes/datatypeProperty/author",
            "http://kelvinlawrence.net/air-routes/datatypeProperty/code",
            "http://kelvinlawrence.net/air-routes/datatypeProperty/date",
            "http://kelvinlawrence.net/air-routes/datatypeProperty/desc",
            "http://kelvinlawrence.net/air-routes/datatypeProperty/type",
            "http://www.w3.org/1999/02/22-rdf-syntax-ns#type",
            "http://www.w3.org/2000/01/rdf-schema#label"
          ]
        }
      ]
    }
  }
}
```

## 搭配圖形摘要端點使用 AWS Identity and Access Management (IAM) 身分驗證
<a name="neptune-graph-summary-iam"></a>

您可以使用 [awscurl](https://github.com/okigan/awscurl) 或任何使用 HTTPS 和 IAM 的任何工具，搭配 IAM 身分驗證安全地存取圖形摘要端點。請參閱 [使用 `awscurl` 搭配臨時憑證，安全地連線至啟用 IAM 身分驗證的資料庫叢集](iam-auth-connect-command-line.md#iam-auth-connect-awscurl) 以了解如何設定適當的憑證。一旦完成了該操作，您就可以提出如下的請求：

```
awscurl "$GRAPH_SUMMARY_ENDPOINT" \
    --region (your region) \
    --service neptune-db
```

**重要**  
建立臨時憑證的 IAM 身分或角色必須附加一個 IAM 政策，允許 [GetGraphSummary](iam-dp-actions.md#getgraphsummary) IAM 動作。

如需您可能遇到的常見 IAM 錯誤清單，請參閱 [IAM 身分驗證錯誤](errors-engine-codes.md#errors-iam-auth)。

## 圖形摘要請求可能傳回的常見錯誤代碼
<a name="neptune-graph-summary-errors"></a>

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/neptune/latest/userguide/neptune-graph-summary.html)

例如，如果您在已啟用 IAM 身分驗證的 Neptune 資料庫中對圖形化摘要端點提出請求，且請求者的 IAM 政策中沒有必要的許可，則您會得到如下的回應：

```
{
  "detailedMessage": "User: arn:aws:iam::(account ID):(user or user name) is not authorized to perform: neptune-db:GetGraphSummary on resource: arn:aws:neptune-db:(region):(account ID):(cluster resource ID)/*",
  "requestId": "7ac2b98e-b626-d239-1d05-74b4c88fce82",
  "code": "AccessDeniedException"
}
```

# Amazon Neptune JDBC 連線能力
<a name="neptune-jdbc"></a>

Amazon Neptune 已發行[開放原始碼 JDBC 驅動程式](https://github.com/aws/amazon-neptune-jdbc-driver)，支援 openCypher、Gremlin、SQL-Gremlin 和 SPARQL 查詢。JDBC 連線能力可讓您透過商業智慧 (BI) 工具 (例如 Tableau) 輕鬆連線至 Neptune。使用 JDBC 驅動程式搭配 Neptune 無需額外成本 — 您仍然只需為耗用的 Neptune 資源支付費用即可。

此驅動程式與 JDBC 4.2 相容，並且至少需要 Java 8。如需如何使用 JDBC 的相關資訊，請參閱 [JDBC API 文件](https://docs.oracle.com/javase/8/docs/technotes/guides/jdbc/)。

GitHub 專案，您可以在其中提出問題和開啟功能請求，包含驅動程式的詳細文件：

**[適用於 Amazon Neptune 的 JDBC 驅動程式](https://github.com/aws/amazon-neptune-jdbc-driver#readme)**
+ [使用 SQL 搭配 JDBC 驅動程式](https://github.com/aws/amazon-neptune-jdbc-driver/blob/develop/markdown/sql.md)
+ [使用 Gremlin 搭配 JDBC 驅動程式](https://github.com/aws/amazon-neptune-jdbc-driver/blob/develop/markdown/gremlin.md)
+ [使用 openCypher 搭配 JDBC 驅動程式](https://github.com/aws/amazon-neptune-jdbc-driver/blob/develop/markdown/opencypher.md)
+ [使用 SPARQL 搭配 JDBC 驅動程式](https://github.com/aws/amazon-neptune-jdbc-driver/blob/develop/markdown/sparql.md)

# Neptune JDBC 驅動程式入門
<a name="neptune-jdbc-getting-started"></a>

若要使用 Neptune JDBC 驅動程式連線至 Neptune 執行個體，JDBC 驅動程式必須部署在與 Neptune 資料庫叢集相同的 VPC 中，或者執行個體必須透過 SSH 通道或負載平衡器使用。SSH 通道可以在驅動程式內部設定，也可以在外部設定。

您可以在[這裡](https://github.com/aws/amazon-neptune-jdbc-driver/releases)下載驅動程式。驅動程式會包裝成單一 JAR 檔案，其名稱類似 `neptune-jdbc-1.0.0-all.jar`。若要使用它，請將 JAR 檔案放在應用程式的 `classpath` 中。或者，如果您的應用程式使用 Maven 或 Gradle，則您可以使用適當的 Maven 或 Gradle 命令，從 JAR 安裝驅動程式。

驅動程式需要一個 JDBC 連線 URL 與 Neptune 連線，形式如下：

```
jdbc:neptune:(connection type)://(host);property=value;property=value;...;property=value
```

GitHub 專案中每個查詢語言的章節都會描述您可以在 JDBC 連線 URL 中為該查詢語言設定的屬性。

如果 JAR 檔案位於應用程式的 `classpath` 中，則不需要任何其他組態。您可以使用 JDBC `DriverManager` 介面和 Neptune 連線字串來連線驅動程式。例如，如果可以透過連接埠 8182 上的端點 `neptune-example.com` 存取您的 Neptune 資料庫叢集，您將能夠像這樣與 OpenCypher 連線：

```
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;

void example() {
    String url = "jdbc:neptune:opencypher://bolt://neptune-example:8182";

    Connection connection = DriverManager.getConnection(url);
    Statement statement = connection.createStatement();

    connection.close();
}
```

GitHub 專案中每種查詢語言的文件章節描述如何在使用該查詢語言時建構連線字串。

# 使用 Tableau 搭配 Neptune JDBC 驅動程式
<a name="neptune-jdbc-tableau"></a>

若要使用 Tableau 搭配 Neptune JDBC 驅動程式，請先下載並安裝最新版本的 [Tableau Desktop](https://www.tableau.com/products/desktop)。下載 Neptune JDBC 驅動程式的 JAR 檔案，以及 Neptune Tableau 連接器檔案 (`.taco` 檔案)。

**在 Mac 上連線到適用於 Neptune 的 Tableau**

1. 將 Neptune JDBC 驅動程式 JAR 檔案放在 `/Users/(your user name)/Library/Tableau/Drivers` 資料夾中。

1. 將 Neptune Tableau 連接器 `.taco` 檔案放在 `/Users/(your user name)/Documents/My Tableau Repository/Connectors` 資料夾中。

1. 如果您已啟用 IAM 身分驗證，請為其設定環境。請注意，在 `.zprofile/`、`.zshenv/`、`.bash_profile` 等中設定的環境變數將無法運作。您必須設定環境變數，GUI 應用程式才能載入它們。

   設定憑證的方法是將您的存取金鑰和私密金鑰放在 `/Users/(your user name)/.aws/credentials` 檔案中。

   設定服務區域的簡單方法就是開啟終端機，並使用應用程式的區域輸入下列命令 (例如 `us-east-1`)：

   ```
   launchctl setenv SERVICE_REGION region name
   ```

   還有其他方法可以設定在重新啟動之後持續存在的環境變數，但是無論您使用哪種技術，都必須設定 GUI 應用程式可以存取的變數。

1. 若要在 Mac 上將環境變數載入至 GUI，請在終端機上輸入以下命令：

   ```
   /Applications/Tableau/Desktop/2021.1.app/Contents/MacOS/Tableau
   ```

**在 Windows 電腦上連線到適用於 Neptune 的 Tableau**

1. 將 Neptune JDBC 驅動程式 JAR 檔案放在 `C:\Program Files\Tableau\Drivers` 資料夾中。

1. 將 Neptune Tableau 連接器 `.taco` 檔案放在 `C:\Users\(your user name)\Documents\My Tableau Repository\Connectors` 資料夾中。

1. 如果您已啟用 IAM 身分驗證，請為其設定環境。

   這可以像設定使用者 `ACCESS_KEY`、`SECRET_KEY` 和 `SERVICE_REGION` 環境變數一樣簡單。

在 Tableau 開啟的情況下，選取視窗左側的**更多**。如果 Tableau 連接器檔案位置正確，您可以在出現的清單中選取**依 AWS的 Amazon Neptune**：

![\[在 Tableau 中選擇 SQL\]](http://docs.aws.amazon.com/zh_tw/neptune/latest/userguide/images/tableau-sql-gremlin.png)


您應該不必編輯連接埠，或新增任何連線選項。輸入您的 Neptune 端點並設定 IAM 和 SSL 組態 (如果您使用的是 IAM，則必須啟用 SSL)。

當您選取**登入**時，如果圖形很大，連線可能需要 30 秒以上的時間。Tableau 正在收集頂點和邊緣，並連接邊緣上的頂點，以及建立視覺效果。

# 對 JDBC 驅動程式連線進行疑難排解
<a name="neptune-jdbc-troubleshooting"></a>

如果驅動程式無法連線到伺服器，請使用 JDBC `Connection` 物件的 `isValid` 函數來檢查連線是否有效。如果此函數傳回 `false` (表示連線無效)，請檢查連線的端點是否正確，以及您是否位於 Neptune DB 叢集的 VPC 中，或者您是否具有叢集的有效 SSH 通道。

如果您收到來自 `DriverManager.getConnection` 呼叫的 `No suitable driver found for (connection string)` 回應，則連線字串開頭處可能發生問題。確保您的連線字串開頭如下所示：

```
jdbc:neptune:opencypher://...
```

若要收集有關連線的詳細資訊，您可以將 `LogLevel` 新增至連線字串，如下所示：

```
jdbc:neptune:opencypher://(JDBC URL):(port);logLevel=trace
```

或者，您也可以在輸入屬性中新增 `properties.put("logLevel", "trace")` 來記錄追蹤資訊。

# Amazon Neptune 引擎更新
<a name="features-engine-updates"></a>

Amazon Neptune 會定期發行引擎更新。您可以使用[執行個體狀態 API](access-graph-status.md) 來判斷您目前安裝的引擎發行版本。

引擎版本列在 [Amazon Neptune 的引擎版本](engine-releases.md)，而修補程式列在[最新更新](doc-history.md)。

您可以在[叢集維護](cluster-maintenance.md)處找到有關如何發行更新，以及如何在您的資料庫中升級 Neptune 引擎的詳細資訊。例如，在[引擎版本編號](cluster-maintenance.md#engine-version-numbers)中會說明版本編號方式。

# 例外狀況處理和重試
<a name="transactions-exceptions"></a>

在 Neptune 上建置強大的應用程式通常意味著為意外做好準備，特別是在處理資料庫傳回的錯誤時。伺服器端例外狀況的最常見回應之一是重試失敗的操作。雖然重試邏輯對於彈性系統至關重要，但您需要了解並非所有錯誤都應該以相同的方式處理。與其依賴一般重試行為，深思熟慮的方法可協助您建置更可靠且更有效率的應用程式。

## 為什麼重試邏輯很重要
<a name="why-retry-logic-matters"></a>

重試邏輯是任何分散式應用程式的關鍵元件。網路不穩定、暫時性資源限制或並行修改衝突等暫時性問題可能會導致操作失敗。在許多情況下，這些失敗並不表示永久問題，可以透過等待並重試來解決。實作穩固的重試策略可確認分散式系統中環境不完美的實際情況，確保更強大的可靠性和持續性，並減少手動介入的需求。

## 不區分重試的風險
<a name="risks-of-indiscriminate-retries"></a>

根據預設，重試每個錯誤可能會導致多種意外後果：
+ **增加爭用** – 當重複重試因高並行而失敗的操作時，整體爭用可能會惡化。這可能會導致交易失敗和效能降低的週期。
+ **資源耗盡** – 不區分重試可能會耗用用戶端和伺服器端的其他系統資源。這可能會導致限流或甚至服務降級。
+ **用戶端的延遲增加** – 過度重試可能會導致用戶端應用程式的嚴重延遲，特別是每次重試都涉及等待期間時。這可能會對使用者體驗和下游程序產生負面影響。

## 制定實際的重試策略
<a name="developing-practical-retry-strategy"></a>

若要建置彈性且有效率的應用程式，請針對應用程式可能遇到的特定錯誤條件，開發量身打造的重試策略。以下是引導您方法的一些考量：
+ **識別可重試的錯誤** – 並非所有例外狀況都應該重試。例如，語法錯誤、身分驗證失敗或無效的查詢不應觸發重試。Neptune 提供[錯誤代碼](https://docs.aws.amazon.com//neptune/latest/userguide/errors-engine-codes.html)和一般建議，這些錯誤可以安全地重試，但您需要實作適合您使用案例的邏輯。
+ **實作指數退避** – 對於暫時性錯誤，請使用指數退避策略逐步增加重試之間的等待時間。這有助於緩解爭用，並降低串聯失敗的風險。
+ **考慮初始暫停長度** – 如果伺服器未獲得足夠的時間來釋放查詢成功所需的資源，則執行第一次重試速度可能會太快，並出現相同的錯誤。在適當情況下，長時間暫停可以減少浪費的請求和伺服器壓力。
+ **新增抖動至退避** – 雖然指數退避有效，但如果許多用戶端同時失敗，然後一起重試，仍可能導致同步重試風暴。將抖動新增為退避延遲的小隨機變化，有助於分散重試嘗試，從而降低所有用戶端同時重試並導致負載再次激增的機會。
+ **限制重試嘗試次數** – 設定合理的重試次數上限，以防止無限迴圈和資源耗盡。
+ **監控和調整** – 持續監控應用程式的錯誤率，並視需要調整重試策略。如果您注意到特定操作的重試次數很高，請考慮操作是否可以最佳化或序列化。

## 範例方案
<a name="example-scenarios"></a>

正確的重試策略取決於失敗的性質、工作負載以及您觀察到的錯誤模式。下表摘要說明一些常見的失敗案例，以及如何將重試策略考量套用至每個案例。針對其他內容，說明段落如下。


|  案例  |  可重試？  |  退避與抖動  |  初始暫停  |  重試限制  |  監控和調整  | 
| --- | --- | --- | --- | --- | --- | 
|  短期查詢上的偶爾 CME  |  是  |  短退避，新增抖動  |  短 （例如 100ms)  |  高  |  留意提高的 CME 速率  | 
|  長時間執行查詢的頻繁 CME  |  是  |  較長的退避，新增抖動  |  較長 （例如 2 秒）  |  適中  |  調查和減少爭用  | 
|  昂貴查詢的記憶體限制  |  是  |  長退避  |  長 （例如 5-10 秒）  |  低  |  最佳化查詢，如果持續，則提醒  | 
|  中等查詢逾時  |  也許可以  |  中等退避，新增抖動  |  中等 （例如 1 秒）  |  低至中度  |  評估伺服器負載和查詢設計  | 

### 案例 1：短查詢的偶爾 CME
<a name="scenario-1-occasional-cme"></a>

對於在短暫、簡單更新期間不常`ConcurrentModificationException`出現的工作負載，這些錯誤通常是暫時性且安全的重試。在第一次重試之前，使用短暫的初始暫停 （例如 100 毫秒）。這次允許清除任何短暫鎖定。結合此值與短指數退避和抖動，以避免同步重試。由於重試成本較低，因此較高的重試限制是合理的。不過，請監控 CME 速率，以捕捉資料中爭用增加的任何趨勢。

### 案例 2：長時間執行的查詢經常使用 CME
<a name="scenario-2-frequent-cme"></a>

如果您的應用程式在長時間執行的查詢上經常看到 CMEs，則表示爭用更嚴重。在此情況下，請從較長的初始暫停 （例如 2 秒） 開始，讓目前的查詢有足夠的時間完成鎖定。使用較長的指數退避並新增抖動。限制重試次數，以避免過度延遲和資源使用。如果爭用持續存在，請檢閱工作負載是否有模式，並考慮序列化更新或減少並行以解決根本原因。

### 案例 3：昂貴查詢的記憶體限制
<a name="scenario-3-memory-limits"></a>

在已知資源密集型查詢期間發生記憶體型錯誤時，只有在長時間的初始暫停 （例如 5 到 10 秒或以上） 後，才能重試，以允許伺服器釋出資源。使用長退避策略並設定低重試限制，因為重複失敗不太可能在沒有變更查詢或工作負載的情況下解決。持續性錯誤應觸發警示，並提示檢閱查詢複雜性和資源用量。

### 案例 4：中度查詢逾時
<a name="scenario-4-timeout-moderate"></a>

中等成本查詢的逾時是更模棱兩可的情況。有時，如果逾時是由於伺服器負載或網路條件的暫時峰值而導致的，則重試可能會成功。從中度初始暫停開始 （例如 1 秒），讓系統有機會復原。套用中度退避並新增抖動，以避免同步重試。將重試限制保持在低至中度，因為重複的逾時可能表示查詢或伺服器容量有更深的問題。監控模式：如果逾時頻繁，請評估查詢是否需要最佳化，或 Neptune 叢集是否佈建不足。

## 監控與可觀測性
<a name="monitoring-and-observability"></a>

監控是任何重試策略的關鍵部分。有效的可觀測性可協助您了解重試邏輯的運作狀態，並在工作負載或叢集組態中需要注意時提供早期訊號。

### MainRequestQueuePendingRequests
<a name="main-request-queue"></a>

此 CloudWatch 指標會追蹤 Neptune 輸入佇列中等待的請求數量。值上升表示查詢正在備份，這可能是過度爭用、資源佈建不足或重試風暴的跡象。監控此指標可協助您找出重試策略何時造成或複合佇列問題，並提示您在失敗升級之前調整方法。

### 其他 CloudWatch 指標
<a name="other-cloudwatch-metrics"></a>

`CPUUtilization`、 `TotalRequestsPerSecond`和 查詢延遲等其他 [Neptune 指標](https://docs.aws.amazon.com/neptune/latest/userguide/cw-metrics.html)提供額外的內容。例如，高 CPU 和 I/O 結合增加的佇列長度，可能表示您的叢集超載，或查詢太大或太頻繁。可以在這些指標上設定 [CloudWatch 警示](https://docs.aws.amazon.com//AmazonCloudWatch/latest/monitoring/AlarmThatSendsEmail.html)，以提醒您異常行為，並協助您將錯誤或重試的峰值與基礎資源限制相關聯。

### Neptune 狀態和查詢 APIs
<a name="neptune-status-query-apis"></a>

[Gremlin 的 Neptune 狀態 API](https://docs.aws.amazon.com//neptune/latest/userguide/gremlin-api-status.html) 及其 [OpenCypher](https://docs.aws.amazon.com//neptune/latest/userguide/access-graph-opencypher-status.html) 和 [SPARQL](https://docs.aws.amazon.com//neptune/latest/userguide/sparql-api-status.html) 的類似 APIs 提供叢集上接受和執行的查詢的即時檢視，這有助於診斷瓶頸或即時了解重試邏輯的影響。

透過結合這些監控工具，您可以：
+ 偵測重試何時導致佇列和效能降低。
+ 識別何時擴展 Neptune 叢集或最佳化查詢。
+ 驗證您的重試策略是否正在解決暫時性故障，而不會遮罩更深的問題。
+ 接收有關新興爭用或資源耗盡的早期警告。

主動監控和提醒對於維持良好的 Neptune 部署至關重要，尤其是隨著應用程式的並行性和複雜性增加。