Get (Ebook) Practical Graph Structures in SQL Server and Azure SQL: Enabling Deeper Insights Using Highly Connected Data by Louis Davidson ISBN 9781484294598, 9781484294581, 1484294599, 1484294580 free all chapters
Get (Ebook) Practical Graph Structures in SQL Server and Azure SQL: Enabling Deeper Insights Using Highly Connected Data by Louis Davidson ISBN 9781484294598, 9781484294581, 1484294599, 1484294580 free all chapters
com
OR CLICK HERE
DOWLOAD EBOOK
ebooknice.com
ebooknice.com
ebooknice.com
ebooknice.com
https://ebooknice.com/product/sat-ii-success-
math-1c-and-2c-2002-peterson-s-sat-ii-success-1722018
ebooknice.com
Louis Davidson
This work is subject to copyright. All rights are solely and exclusively
licensed by the Publisher, whether the whole or part of the material is
concerned, specifically the rights of translation, reprinting, reuse of
illustrations, recitation, broadcasting, reproduction on microfilms or in
any other physical way, and transmission or information storage and
retrieval, electronic adaptation, computer software, or by similar or
dissimilar methodology now known or hereafter developed.
The publisher, the authors, and the editors are safe to assume that the
advice and information in this book are believed to be true and accurate
at the date of publication. Neither the publisher nor the authors or the
editors give a warranty, expressed or implied, with respect to the
material contained herein or for any errors or omissions that may have
been made. The publisher remains neutral with regard to jurisdictional
claims in published maps and institutional affiliations.
1. Introduction to Graphs
Louis Davidson1
(1) Cleveland, TN, USA
Graph Fundamentals
While most readers will have the explicit goal of applying a graph to a
specific problem they are trying to solve, it is best to start at the
beginning and discuss what a graph is in the pure sense. (If you don’t
care, you can skip to Chapter 3 where the T-SQL code starts!) Going
through the fundamentals will help you free your mind from
preconceived notions. Perhaps, more importantly, you can ignore the
limitations of the tools and specific problem sets you may wish to solve
and just think about the whole problem set.
In math, there are the concepts of “pure” math and “applied” math.
Pure math is math for math’s sake. It is there to ask, “what can be done
with a construct?” without asking the limiting questions of, “is this
helpful code to solve my problem or, even more importantly, any
problem?” Applied math is more or less the sort of thing we typical
computer architects/programmers are typically interested in since we
have a problem and want to find something to help us with that
problem (and immediately so). Most of the time, solutions are only
interesting if they can solve the specific problems we currently know
about and have a manager riding on our back.
However, I always prefer to start just trying to see what I can
accomplish with a new tool before getting my hands dirty
(metaphorically, of course; as a programmer, my hands never get dirty
at work unless the day’s snack includes chocolate).
Some of the things I will discuss will then be familiar in
understanding what we might do when looking for patterns in the data
and eventually translating into algorithms. Some designs may not be
realistically possible due to current computing limitations in SQL
Server (or any graph database platform) or reasonable hardware
limitations at the time of writing in 2023. Having written my first book
in 2000, it astounds me how different this statement feels to me 23
years later sitting here with a computer on my desk that has more
power that medium to large corporations were running on when I first
wrote T-SQL.
In one of my sample databases you can download, I have millions of
rows in just one table, and I can process reasonable queries on my
desktop computer in mere minutes. Limitations always exist, but there
are fewer and fewer limitations for every generation of computer
architecture that passes.
My goal here in this first chapter (and to a large extent, the second
chapter) is to simply introduce some of the terms and concepts around
graphs to help you understand how graphs are shaped and, eventually,
processed.
Definition
Graphs are based on two primary data structures: nodes (or in math
terms, vertices), and edges. Nodes represent a thing that one might
care about, much like a table in a relational database. Edges establish a
connection between exactly one or two nodes (when the node count is
one, it means the node is related to itself.) A graph is defined as being a
set of nodes and a set of edges.
In a graph database, a node is like most any table with attributes
describing what the node represents. The edge is analogous to a many-
to-many relationship table with at least attributes to represent the
node that the relationship is from and which it is to. You will see that
two major things set these new concepts apart from a relational
implementation.
First, the from and the to in an edge generally can be from any node
object. Whereas a relational table column used to reference another
table value communicates that it is a foreign key from Table X and
nothing else, the from and to attributes of an edge can be from multiple
different node types if you so desire.
Tip I am fully aware that you can put any value into a column, so
every foreign key value in a column needn’t come from the same
table. But that is not how it should be done because data where a
column can mean multiple things is very confusing in a relational
table. Graph structures work very similar to how relational tables
work. Still, they have special properties that allow two rows to
contain data from multiple sources without confusing the
user/engine.
The two graph diagrams in Figure 1-4 are copies of the same graph.
The next concept is related, in that we will look at graphs with the same
shape but different nodes. When a graph has the same node and edge
shape (meaning the same nodes and edges, not diagram shape,) the
graphs are referred to as being isomorphic graphs. For example, the
two graphs in Figure 1-5 are not equal but they are isomorphic because
they have the same shape in their set of data (regardless of whether you
draw them as a square or not).
Figure 1-5 Two isomorphic graph structures
This concept of isomorphism will be, if not actually referred to using
the exact term, interesting in your usage of graphs on occasion.
Consider the set of nodes in Figure 1-6.
Now, consider that the nodes {Larry, The Who, Rolling Stones},
which form what is known as a subgraph (a set of nodes and edges
that is a part of a graph) of the more complete graph, are isomorphic to
{Fred, The Who, Rolling Stones}. It isn’t a difficult leap to see that since
Fred and Larry are both connected to two similar nodes, that an
additional edge {Fred, Beatles} might be a possibility for Fred. So, the
company may then wish to suggest “Have you heard of The Beatles (or
do you live under a rock)?” Of course, Fred may not be a fan of John,
Paul, George, and Ringo; but the goal of many graphs may be to look for
common traits and then suggest ways to make them more common.
Take this further and you may see patterns occurring from completely
different subgraphs that may indicate a repeatable pattern.
An important concept in subgraphs is a walk in a graph. This refers
to how you can traverse from node to node. For example, in the first
graph in Figure 1-6, starting at Larry you can find a walk from Larry ->
TheWho -> Rolling Stones -> Beatles -> Larry. You can also find many
other walks from any node to any node in this sample graph, since
every node in the graph is connected to every other node. Another term
for a walk is a path, which may be a bit more common since the
operator you will use in SQL Server 2019 and later to find a walk is
named SHORTEST_PATH.
You will often use this concept of a walk to determine the closest
one node is to another. For example, in the second variant of the graph,
the distance from Fred to The Who and Rolling Stones is 1 and to the
Beatles is 2. If you are a user of LinkedIn, you have seen this concept
when you see that you are a first-level connection or second or more to
other people. A second-level connection means you are connected
through one intermediate node.
A concept that is interesting if likely not particularly necessary in
programming typical graph structures is a Euler (pronounced Oiler)
Walk. An Euler Walk consists of the starting node being touched twice
and every edge in the graph touched exactly once. For example,
consider the graphs in Figure 1-7.
Figure 1-7 Graph diagrams to demonstrate walks
Realistically the limitation will come down to the thing that all
modeling decisions come to: semantics. What does the relationship
mean and how will it be used to mean one or more relationships? For
example, you might only logically have one edge between persons
indicating that person is a biological parent to a person; on the other
hand, multiple edges between person and movie could make sense: one
for actor, one for producer, one for director, and so on.
One last bit of graph theory I want to cover is that of a connected
graph. In a connected graph, there is a walk from every node in the
graph to every other node. The graph will be in one or more pieces in a
disconnected graph. In Figure 1-8, we have the simplest connected
graph with more than one node in 1-8A and the simplest disconnected
graph in 1-8B. The graph in 1-8A is said to be in one piece, and the
graph in 1-8B is in two pieces.
When you have a connected graphs and removing an edge will cause
it to be broken into more pieces, the edge is referred to as a bridge
edge. Consider the graph in Figure 1-10.
Figure 1-14 Graph examples to demonstrate processing acyclic and cyclic directed
graph
In Figure 1-14A, an acyclic graph, you can walk the graph from N1-
>N2->N3->N4 directly using a simple algorithm of going node to node,
touching all the nodes with no problem. But in Figure 1-14B, the
algorithm of going from node to node is made difficult by N1->N2->N3-
>N1, because what to do next? Cycle through the nodes again? Or stop
processing? All the results from starting at N1 would be repeated, but
what does this mean for the graph that you are modeling? You can
remember this mentally when manually tracing through, but the
programming gets more complex if you look at millions or billions of
nodes (the programming is not impossible, just more complicated).
This ability to be able to find a simple connection/walk from two
nodes in a graph is referred to as transitive closure. Once you have
hold of this power, you can do all forms of interesting things with
graphs, such as determining if you are connected to Kevin Bacon and
what is the shortest path through the people you are connected to that
you will need to bug to get tickets to see The Bacon Brothers in concert
when they come to your town.
In a more database design-oriented concern, consider what can be
modeled with an acyclic graph versus a cyclic one. More will be covered
in Chapter 2, but if you are modeling containership, like a bill of
materials (a data structure used in packaging/assembling items, where
products that are a part of other products are modeled using a graph), a
cycle in the graph could give you odd results. Consider the graph in
Figure 1-15.
Summary
In this chapter, the goal was to introduce some of the core concepts that
are used when discussing graph topics. Many of these topics may show
up all over the book, but also some may not. The goal of this chapter
was to briefly introduce concepts that will help you to envision what a
graph is and how a graph might be used as you start to solve complex
problems with graphs.
© The Author(s), under exclusive license to APress Media, LLC, part of Springer
Nature 2023
L. Davidson, Practical Graph Structures in SQL Server and Azure SQL
https://doi.org/10.1007/978-1-4842-9459-8_2
Basic Implementation
As discussed in the previous chapter, the basic building blocks of a
graph are nodes and edges. A node is basically the same thing as any
relational database table representing some specific concept. An edge
represents a link between two rows in these tables, much like a typical
many-to-many resolution table does in a relational database.
So, say you have the graph shown in Figure 2-1.
Figure 2-1 Simple graph
You need a table to hold the N1 and N2 nodes. These nodes could be
of the same type or different types. For example, they could be one
person being the friend or family member of the other, or a person
being a fan of a certain football team. Let’s assume for this example that
they are the same type (and in the future, if I want them to be two
different types of objects, I will label the nodes as such).
For my examples, I will use data that would be at home in many
relational tables for most examples, simply because that is how you will
typically think of the data. In the following two chapters, I will establish
how SQL Server implements graph structures, but for now, just take the
data structures to be basically as you have built in SQL Server tables
before. To implement the structure in Figure 2-1, say you have the
following rows in a table to represent the two nodes:
Node
------
N1
N2
Now you need a data structure that represents the edge, like this:
FromNode ToNode
-------- -------
N1 N2
Acyclic Graphs
The easiest graphs to work with in a relational database are acyclic. The
reason comes down to the method used to process graphs in a
relational setting, the breadth-first algorithm (or relational
recursion). This algorithm was created for relational processing,
because the typical recursion used to process these data structures did
not fit well with the set-based nature of a relational database.
For example, consider the graph in Figure 2-2.
Figure 2-2 Sample graph structure
Processing this using a typical recursive manner, you choose your
starting point as N1 and then see if this node has one unprocessed
child. It does, so fetch N11. See if N11 has unprocessed children. Yes,
N111. N111 has no unprocessed child nodes, so whatever you are doing
with the data of the node, you add that to an output data structure.
Then step back up to N11 and get the next child node. And keep going.
This is referred to as a depth-first algorithm.
Common operations are counting nodes, summing sales from that
node, and so on. For your example, let’s just say you are counting child
nodes. So, you recurse back to N11 and add 1 to the child count. Then
you check for more child nodes, and you have more. Over and over. You
stop when every node has been processed in the subgraph that started
with your starting point.
This works great for certain kinds of programming languages but
terrible for relational ones where set-based processing is the clearly
desired method of programming. It works with sets of data, so that is
the kind of processing that has been devised for working with graphs in
the manner that relations engines work.
For a breadth-first algorithm, instead of digging down in the
structure, you take a starting point and then get all of the children of
that node. Then the children of those nodes, all at once. Taking that
same diagram, let’s break this down into a series of three queries on the
data, as seen in Figure 2-3.
Figure 2-3 Sample graph indicating the different levels that will be fetched in a
breadth-first query
You query for the starting point. In this case, it’s one node, but it
could be any number of nodes (in fact, that is the basis of some of the
code in this book to do things like starting at every node
simultaneously!). Your breadth-first algorithm is to query:
SELECT GraphId
FROM GraphObject
WHERE GraphId = @startingPoint --starting point =
N1
Trees
By far the most common graph that has been implemented in relational
databases for many years is a tree. A tree is a structure that requires
that every node have either zero or one parent, and no more. Consider a
real tree (or in the case of Figure 2-5, a glorious reproduction of a tree
from Disney’s Animal Kingdom theme park).
It has one trunk that goes into the ground. Either direction out
(down to the roots or up to the branches), you can see the analogy. Any
branch can be from the trunk or another branch, but it can only be one
of these. Branches don’t grow together and reform as one. (At least not
typically, and this isn’t botany class!) Nodes that do not have any child
nodes are referred to as leaf nodes, much like the leaves on the
branches stand alone.
My breadth-first example structure was a tree, reincluded as Figure
2-6.
Figure 2-6 Example tree repeated
To represent this in an adjacency list structure, you have rows like
From To
———- ———-
N1 N11
N11 N111
N11 N112
N11 N113
N1 N12
And so on. In order to make sure that the tree is always a tree, you
need to protect one main condition: unique to values. Since a child row
can only have one parent in a tree, having a uniqueness constraint on
that column of the adjacency list ensures it is a tree.
The other thing you typically need to do is include a constraint of
some sort to make sure that the from value does not equal the to
value. This is the only cycle that the uniqueness constraint will not stop
(though a duplicated to and from value basically makes the row a root
and a leaf and would likely be discovered quickly…but one of my mottos
is that bad data doesn’t happen if you don’t let it occur at all).
While all tree structures require a single root, a table structure such
as this could contain multiple tree structures. In some cases, a row with
NULL, N1 could be included in the structure as the starting point
when you create the tree. You can make sure there is only one using a
unique index, which only allows one NULL value. (SQL Server treats a
NULL value as distinct in indexes, unlike in comparisons, so that would
make sure that you had only one root node.). You could allow greater
than one root node by using a filtered UNIQUE index that ignores NULL
values. If you want to make sure the NULL row is never deleted, a
trigger object can be used, which is especially useful if you have users
that can delete rows in an ad-hoc manner.
If you need to model multiple tree structures, it is possible to just
create multiple edge objects, each with a distinct purpose. For example,
consider a company reporting structure. There are multiple projects
going on where a person is in the project management hierarchy, and
typically there is a hierarchy for dealing with HR type things. So, you
could create
And you could also create the same table again for every project.
Alternatively, you could model this as one structure that allows for
many trees to coincide in the same structure.
All the indexes discussed for the general tree structures would still
make sense, but you would include the HierarchyName in the object
because the uniqueness stands only for one project if an employee can
be on multiple projects.
It might just make sense to have the ManagementEdge as
modeled, but then have the project hierarchy be in its own
ProjectManagementEdge since they serve different purposes.
Determining how to model your graph is pretty much the same
challenge as with any database: making the structures match your
requirements with the tightness to prevent bad data and the flexibility
to do what the customer wants to do.
Finally, note that you can implement variations of parent
cardinalities to implement strict types of trees. For example, a binary
or simple tree is defined as a tree where you can only have two
children for each node. Consider Figure 2-7.
One consideration you must have for creating a binary tree (or
really any limited cardinality of child row) is how to make sure a node
that violates the structure child is not created. There are a few methods
that work. Using triggers to count the number of nodes is one, as is
adding a node number and using a check constraint to only allow values
of 1 and 2, along with a unique index on the from item.
So
The downside is that you have this column that seems to indicate an
order to the nodes that is important. (In some systems you may desire
that ordering, perhaps to guide the user in a direction or to sort the
nodes.)
It can also be argued that some data integrity of this sort could be
deferred, and you simply check after changes have been made and fix
issues later, especially if your requirements get more complicated.
Regardless of how you make sure integrity is enforced, it needs to be
enforced.
Another important concept when working with trees is how
balanced the tree is. For example, consider Figure 2-8.
While items can have more than one predecessor in the graph (in
Figure 2-9, you can see that the Hanging Kit has two predecessors),
every starting node you pick can be treated as if it was the root node of
a tree. Start at the Hanging Kit, and you get a tree where the next level
nodes are Hanger and Nail Pack. The Nail Pack contains two Nails (in
your actual implementation, you will use a magnitude on the Nail Pack
to Nail edge to represent multiples. I will discuss more about edge
magnitudes in Chapter 3 because this is important to some designs).
Hence, when you traverse/process a bill of materials (or any acyclic
graph), you often can treat it like a tree when fetching the child rows,
not having to worry about cycles. When you load the bill of materials
structure, this is when you must make sure to not introduce a cycle.
Unlike trees where you can limit a node to exist in only one parent row
with an index, in this case you cannot protect against cycles with a
simple constraint.
Note that, depending on the tools you are using, the idea of treating
parts of a bill of materials like a tree may fall apart if you need to see
the entire structure due to how some graph code works. This will be
clearer in Chapters 3 and 7.
As you are adding nodes to a polyhierarchy, you need to do a query
to search for cycles. Like the example back in Figure 2-4 (repeated as
Figure 2-10), consider this graph before the edge between N3 and N1
was added.
All would have been fine. But that new edge from N3 to N1 creates a
cycle. Finding the cycle condition will basically use the breadth-first
algorithm discussed previously, but in this case, your query is looking
for a match to the node where you start. So, for each iteration, you are
looking for FirstNodeId = CurrentNodeId; if found, then this is
no longer an acyclic graph (and you will have to take the appropriate
action, like rolling back the insert of that edge).
This can be done in a stored procedure or even a trigger if you want
to keep the cycle from happening at all. Of course, if you need optimum
performance, you might have to defer cycle checking (especially for
very large graphs), although this also has downsides if the data is also
actively queried.
As I go through the examples in the book, I will frequently use a
stored procedure to manage and query new nodes because rarely are
the user key values the internal values you use for surrogate keys.
Random documents with unrelated
content Scribd suggests to you:
Vraiment, voilà bien de la poudre perdue et bien noyée! à grande
eau!... C'est de la belle besogne! On ne regarde pas à l'eau, dans la
demeure du Lac! Si ça continue, tout le lac va entrer dans la cave...
Car, en vérité, on ne sait plus maintenant où elle va s'arrêter...
Nous voici sortis de la cave et l'eau monte toujours...
Et l'eau aussi sort de la cave, s'épand sur le plancher... Si cela
continue, toute la demeure du Lac va en être inondée. Le plancher
de la chambre des miroirs est lui-même un vrai petit lac dans lequel
nos pieds barbotent. C'est assez d'eau comme cela! Il faut qu'Erik
ferme le robinet: Erik! Erik! Il y a assez d'eau pour la poudre! Tourne
le robinet! Ferme le scorpion!
Mais Erik ne répond pas... On n'entend plus rien que l'eau qui
monte... nous en avons maintenant jusqu'à mi-jambe!...
—Christine! Christine! l'eau monte! monte jusqu'à nos genoux, crie
M. de Chagny.
Mais Christine ne répond pas... on n'entend plus rien que l'eau qui
monte.
Rien! rien! dans la chambre à côté... Plus personne! personne pour
tourner le robinet! personne pour fermer le scorpion!
Nous sommes tout seuls, dans le noir, avec l'eau noire qui nous
étreint, qui grimpe, qui nous glace! Erik! Erik! Christine! Christine!
Maintenant, nous avons perdu pied et nous tournons dans l'eau,
emportés dans un mouvement de rotation irrésistible, car l'eau
tourne avec nous et nous nous heurtons aux miroirs noirs qui nous
repoussent... et nos gorges soulevées au-dessus du tourbillon
hurlent...
Est-ce que nous allons mourir ici? noyés dans la chambre des
supplices?... Je n'ai jamais vu ça? Erik, au temps des Heures Roses
de Mazenderan, ne m'a jamais montré cela par la petite fenêtre
invisible!... Erik! Erik! Je t'ai sauvé la vie! Souviens-toi!... Tu étais
condamné!... Tu allais mourir!... Je t'ai ouvert les portes de la vie!...
Erik!...
Ah! nous tournons dans l'eau comme des épaves!...
Mais j'ai saisi tout à coup de mes mains égarées le tronc de l'arbre
de fer!... et j'appelle M. de Chagny... et nous voilà tous les deux
suspendus à la branche de l'arbre de fer...
Et l'eau monte toujours!
Ah! ah! rappelez-vous! Combien y a-t-il d'espace entre la branche de
l'arbre de fer et le plafond en coupole de la chambre des miroirs?...
Tâchez à vous souvenir!... Après tout, l'eau va peut-être s'arrêter...
elle trouvera sûrement son niveau... Tenez! il me semble qu'elle
s'arrête!... Non! non! horreur!... À la nage! À la nage!... nos bras qui
nagent s'enlacent; nous étouffons!... nous nous battons dans l'eau
noire!... nous avons déjà peine à respirer l'air noir au-dessus de l'eau
noire... l'air qui fuit, que nous entendons fuir au-dessus de nos têtes
par je ne sais quel appareil de ventilation... Ah! tournons! tournons!
tournons jusqu'à ce que nous ayons trouvé la bouche d'air... nous
collerons notre bouche à la bouche d'air... Mais les forces
m'abandonnent, j'essaie de me raccrocher aux murs! Ah! comme les
parois de glace sont glissantes à mes doigts qui cherchent... Nous
tournons encore!... Nous enfonçons... Un dernier effort!... Un dernier
cri!... Erik!... Christine!... glou, glou, glou!... dans les oreilles!... glou,
glou, glou!... au fond de l'eau noire, nos oreilles font glou-glou!... Et
il me semble encore, avant de perdre tout à fait connaissance,
entendre entre deux glouglous... «Tonneaux!... tonneaux!... Avez-
vous des tonneaux à vendre?»
XXVII
C'est ici que se termine le récit écrit que m'a laissé le Persan.
Malgré l'horreur d'une situation qui semblait définitivement les vouer
à la mort, M. de Chagny et son compagnon furent sauvés par le
dévouement sublime de Christine Daaé. Et je tiens tout le reste de
l'aventure de la bouche du daroga lui-même.
Quand j'allai le voir, il habitait toujours son petit appartement de la
rue de Rivoli, en face des Tuileries. Il était bien malade et il ne fallait
rien moins que toute mon ardeur de reporter-historien au service de
la vérité pour le décider à revivre avec moi l'incroyable drame. C'était
toujours son vieux et fidèle domestique Darius qui le servait et me
conduisait auprès de lui. Le daroga me recevait au coin de la fenêtre
qui regarde le jardin, assis dans un vaste fauteuil où il essayait de
redresser un torse qui n'avait pas dû être sans beauté. Notre Persan
avait encore ses yeux magnifiques, mais son pauvre visage était bien
fatigué. Il avait fait raser entièrement sa tête qu'il couvrait à
l'ordinaire d'un bonnet d'astrakan; il était habillé d'une vaste
houppelande très simple dans les manches de laquelle il s'amusait
inconsciemment à tourner les pouces, mais son esprit était resté fort
lucide.
Il ne pouvait se rappeler les affres anciennes sans être repris d'une
certaine fièvre et c'est par bribes que je lui arrachai la fin
surprenante de cette étrange histoire. Parfois, il se faisait prier
longtemps pour répondre à mes questions, et parfois exalté par ses
souvenirs il évoquait spontanément devant moi, avec un relief
saisissant, l'image effroyable d'Erik et les terribles heures que M. de
Chagny et lui avaient vécues dans la demeure du Lac.
Il fallait voir le frémissement qui l'agitait quand il me dépeignait son
réveil dans la pénombre inquiétante de la chambre Louis-Philippe...
après le drame des eaux... Et voici la fin de cette terrible histoire,
telle qu'il me l'a racontée de façon à compléter le récit écrit qu'il
avait bien voulu me confier:
En ouvrant les yeux, le daroga s'était vu étendu sur un lit... M. de
Chagny était couché sur un canapé, à côté de l'armoire à glace. Un
ange et un démon veillaient sur eux...
Après les mirages et illusions de la chambre des supplices, la
précision des détails bourgeois de cette petite pièce tranquille,
semblait avoir été encore inventée dans le dessein de dérouter
l'esprit du mortel assez téméraire pour s'égarer dans ce domaine du
cauchemar vivant. Ce lit-bateau, ces chaises d'acajou ciré, cette
commode et ces cuivres, le soin avec lequel ces petits carrés de
dentelle au crochet étaient placés sur le dos des fauteuils, la pendule
et de chaque côté de la cheminée les petits coffrets à l'apparence si
inoffensive... enfin, cette étagère garnie de coquillages, de pelotes
rouges pour les épingles, de bateaux en nacre et d'un énorme œuf
d'autruche... le tout éclairé discrètement par une lampe à abat-jour
posée sur un guéridon... tout ce mobilier qui était d'une laideur
ménagère touchante, si paisible, si raisonnable «au fond des caves
de l'Opéra», déconcertait l'imagination plus que toutes les
fantasmagories passées.
Et l'ombre de l'homme au masque, dans ce petit cadre vieillot, précis
et propret, n'en apparaissait que plus formidable. Elle se courba
jusqu'à l'oreille du Persan et lui dit à voix basse:
—Ça va mieux, daroga?... Tu regardes mon mobilier?... C'est tout ce
qui me reste de ma pauvre misérable mère...
Il lui dit encore des choses qu'il ne se rappelait plus; mais—et cela
lui paraissait bien singulier—le Persan avait le souvenir précis que,
pendant cette vision surannée de la chambre Louis-Philippe, seul
Erik parlait. Christine Daaé ne disait pas un mot; elle se déplaçait
sans bruit et comme une Sœur de charité qui aurait fait vœu de
silence... Elle apportait dans une tasse un cordial... ou du thé
fumant... L'homme au masque la lui prenait des mains et la tendait
au Persan.
Quant à M. de Chagny, il dormait...
Erik dit en versant un peu de rhum dans la tasse du daroga et en lui
montrant le vicomte étendu:
—Il est revenu à lui bien avant que nous puissions savoir si vous
seriez encore vivant un jour, daroga. Il va très bien... Il dort... Il ne
faut pas le réveiller...
Un instant, Erik quitta la chambre et le Persan, se soulevant sur son
coude, regarda autour de lui... Il aperçut, assise au coin de la
cheminée, la silhouette blanche de Christine Daaé. Il lui adressa la
parole... il l'appela... mais il était encore très faible et il retomba sur
l'oreiller... Christine vint à lui, lui posa la main sur le front, puis
s'éloigna... Et le Persan se rappela qu'alors, en s'en allant, elle n'eut
pas un regard pour M. de Chagny qui, à côté, il est vrai, bien
tranquillement dormait... et elle retourna s'asseoir dans son fauteuil,
au coin de la cheminée, silencieuse comme une Sœur de charité qui
a fait vœu de silence...
Erik revint avec de petits flacons qu'il déposa sur la cheminée. Et
tout bas encore, pour ne pas éveiller M. de Chagny, il dit au Persan,
après s'être assis à son chevet et lui avoir tâté le pouls:
—Maintenant, vous êtes sauvés tous les deux. Et je vais tantôt vous
reconduire sur le dessus de la terre, pour faire plaisir à ma femme.
Sur quoi il se leva, sans autre explication, et disparut encore.
Le Persan regardait maintenant le profil tranquille de Christine Daaé
sous la lampe. Elle lisait dans un tout petit livre à tranche dorée
comme on en voit aux livres religieux. L'Imitation a de ces éditions-
là. Et le Persan avait encore dans l'oreille le ton naturel avec lequel
l'autre avait dit: «Pour faire plaisir à ma femme...»
Tout doucement, le daroga appela encore, mais Christine devait lire
très loin, car elle n'entendit pas...
Erik revint... fit boire au daroga une potion, après lui avoir
recommandé de ne plus adresser une parole à «sa femme» ni à
personne, parce que cela pouvait être très dangereux pour la santé
de tout le monde.
À partir de ce moment, le Persan se souvient encore de l'ombre
noire d'Erik et de la silhouette blanche de Christine qui glissaient
toujours en silence à travers la chambre, se penchaient au-dessus de
lui et au-dessus de M. de Chagny. Le Persan était encore très faible
et le moindre bruit, la porte de l'armoire à glace qui s'ouvrait en
grinçant, par exemple, lui faisait mal à la tête... et puis il s'endormit
comme M. de Chagny.
Cette fois, il ne devait plus se réveiller que chez lui, soigné par son
fidèle Darius, qui lui apprit qu'on l'avait, la nuit précédente, trouvé
contre la porte de son appartement, où il avait dû être transporté
par un inconnu, lequel avait eu soin de sonner avant de s'éloigner.
Aussitôt que le daroga eut recouvré ses forces et sa responsabilité, il
envoya demander des nouvelles du vicomte au domicile du comte
Philippe.
Il lui fut répondu que le jeune homme n'avait pas reparu et que le
comte Philippe était mort. On avait trouvé son cadavre sur la berge
du Lac de l'Opéra, du côté de la rue Scribe. Le Persan se rappela la
messe funèbre à laquelle il avait assisté derrière le mur de la
chambre des miroirs et il ne douta plus du crime ni du criminel. Sans
peine, hélas! connaissant Erik, il reconstitua le drame. Après avoir
cru que son frère avait enlevé Christine Daaé, Philippe s'était
précipité à sa poursuite sur cette route de Bruxelles, où il savait que
tout était préparé pour une telle aventure. N'y ayant point rencontré
les jeunes gens, il était revenu à l'Opéra, s'était rappelé les étranges
confidences de Raoul sur son fantastique rival, avait appris que le
vicomte avait tout tenté pour pénétrer dans les dessous du théâtre
et enfin qu'il avait disparu, laissant son chapeau dans la loge de la
diva, à côté d'une boîte de pistolets. Et le comte, qui ne doutait plus
de la folie de son frère, s'était à son tour lancé dans cet infernal
labyrinthe souterrain. En fallait-il davantage, aux yeux du Persan,
pour que l'on retrouvât le cadavre du comte sur la berge du Lac, où
veillait le chant de la sirène, la sirène d'Erik, cette concierge du Lac
des Morts?
Aussi le Persan n'hésita pas. Épouvanté de ce nouveau forfait, ne
pouvant rester dans l'incertitude où il se trouvait relativement au
sort définitif du vicomte et de Christine Daaé, il se décida à tout dire
à la justice.
Or l'instruction de l'affaire avait été confiée à M. le juge Faure et
c'est chez lui qu'il s'en alla frapper. On se doute de quelle sorte un
esprit sceptique, terre à terre, superficiel (je le dis comme je le
pense) et nullement préparé à une telle confidence, reçut la
déposition du daroga. Celui-ci fut traité comme un fou.
Le Persan, désespérant de se faire jamais entendre, s'était mis alors
à écrire. Puisque la justice ne voulait pas de son témoignage, la
presse s'en emparerait peut-être, et il venait un soir de tracer la
dernière ligne du récit que j'ai fidèlement rapporté ici quand son
domestique Darius lui annonça un étranger qui n'avait point dit son
nom, dont il était impossible de voir le visage et qui avait déclaré
simplement qu'il ne quitterait la place qu'après avoir parlé au
daroga.
Le Persan, pressentant immédiatement la personnalité de ce
singulier visiteur, ordonna qu'on l'introduisît sur-le-champ.
Le daroga ne s'était pas trompé.
C'était le Fantôme! C'était Erik!
Il paraissait d'une faiblesse extrême et se retenait au mur comme s'il
craignait de tomber... Ayant enlevé son chapeau, il montra un front
d'une pâleur de cire. Le reste du visage était caché par le masque.
Le Persan s'était dressé devant lui.
—Assassin du comte Philippe, qu'as-tu fait de son frère et de
Christine Daaé?
À cette apostrophe formidable, Erik chancela et garda un instant le
silence, puis, s'étant traîné jusqu'à un fauteuil, il s'y laissa tomber en
poussant un profond soupir. Et là, il dit à petites phrases, à petits
mots, à court souffle:
—Daroga, ne me parle pas du comte Philippe... Il était mort... déjà...
quand je suis sorti de ma maison... il était mort... déjà... quand... la
sirène a chanté... c'est un accident... un triste... un...
lamentablement triste... accident... Il était tombé bien
maladroitement et simplement et naturellement dans le Lac!...
—Tu mens! s'écria le Persan.
Alors Erik courba la tête et dit:
—Je ne viens pas ici... pour te parler du comte Philippe... mais pour
te dire que... je vais mourir...
—Où sont Raoul de Chagny et Christine Daaé?...
—Je vais mourir.
—Raoul de Chagny et Christine Daaé?
—... d'amour... daroga... je vais mourir d'amour... c'est comme cela...
je l'aimais tant!... Et je l'aime encore, daroga, puisque j'en meurs, je
te dis... Si tu savais comme elle était belle quand elle m'a permis de
l'embrasser vivante, sur son salut éternel... C'était la première fois,
daroga, la première fois, tu entends, que j'embrassais une femme...
Oui, vivante, je l'ai embrassée vivante et elle était belle comme une
morte?...
Le Persan s'était levé et il avait osé toucher Erik. Il lui secoua le
bras.
—Me diras-tu enfin si elle est morte ou vivante?...
—Pourquoi me secoues-tu ainsi? répondit, Erik avec effort... Je te dis
que c'est moi qui vais mourir... oui, je l'ai embrassée vivante...
—Et maintenant, elle est morte?
—Je te dis que je l'ai embrassée comme ça sur le front... et elle n'a
point retiré son front de ma bouche!... Ah! c'est une honnête fille!
Quant à être morte, je ne le pense pas, bien que cela ne me regarde
plus... Non! non! elle n'est pas morte! Et il ne faudrait pas que
j'apprenne que quelqu'un a touché un cheveu de sa tête! C'est une
brave et honnête fille qui t'a sauvé la vie, par-dessus le marché,
daroga, dans un moment où je n'aurais pas donné deux sous de ta
peau de Persan. Au fond, personne ne s'occupait de toi. Pourquoi
étais-tu là avec ce petit jeune homme? Tu allais mourir par-dessus le
marché! Ma parole, elle me suppliait pour son petit jeune homme,
mais je lui avais répondu que, puisqu'elle avait tourné le scorpion,
j'étais devenu par cela même, et de sa bonne volonté, son fiancé et
qu'elle n'avait pas besoin de deux fiancés, ce qui était assez juste;
quant à toi, tu n'existais pas, tu n'existais déjà plus, je te le répète,
et tu allais mourir avec l'autre fiancé!
Seulement, écoute bien, daroga, comme vous criiez comme des
possédés à cause de l'eau, Christine est venue à moi, ses beaux
grands yeux bleus ouverts et elle m'a juré, sur son salut éternel,
qu'elle consentait à être ma femme vivante! Jusqu'alors, dans le
fond de ses yeux, daroga, j'avais toujours vu ma femme morte;
c'était la première fois que j'y voyais ma femme vivante. Elle était
sincère, sur son salut éternel. Elle ne se tuerait point. Marché conclu.
Une demi-minute plus tard, toutes les eaux étaient retournées au
Lac, et je tirais ta langue, daroga, car j'ai bien cru, ma parole, que tu
y resterais!... Enfin!... Voilà! C'était entendu! je devais vous reporter
chez vous sur le dessus de la terre. Enfin, quand vous m'avez eu
débarrassé le plancher de la chambre Louis-Philippe, j'y suis revenu,
moi, tout seul.
—Qu'avais-tu fait du vicomte de Chagny? interrompit le Persan.
—Ah! tu comprends... celui-là, daroga, je n'allais pas comme ça le
reporter tout de suite sur le dessus de la terre... C'était un otage...
Mais je ne pouvais pas non plus le conserver dans la demeure du
lac, à cause de Christine; alors je l'ai enfermé bien confortablement,
je l'ai enchaîné proprement (le parfum de Mazenderan l'avait rendu
mou comme une chiffe) dans le caveau des communards qui est
dans la partie la plus déserte de la plus lointaine cave de l'Opéra,
plus bas que le cinquième dessous, là où personne ne va jamais et
d'où l'on ne peut se faire entendre de personne. J'étais bien
tranquille et je suis revenu auprès de Christine. Elle m'attendait...
À cet endroit de son récit, il paraît que le Fantôme se leva si
solennellement que le Persan qui avait repris sa place dans son
fauteuil dut se lever, lui aussi, comme obéissant au même
mouvement et sentant qu'il était impossible de rester assis dans un
moment aussi solennel et même (m'a dit le Persan lui-même) il ôta,
bien qu'il eût la tête rase, son bonnet d'astrakan.
—Oui! Elle m'attendait, reprit Erik, qui se prit à trembler comme une
feuille, mais à trembler d'une vraie émotion solennelle... elle
m'attendait toute droite, vivante, comme une vraie fiancée vivante,
sur son salut éternel... Et quand je me suis avancé, plus timide qu'un
petit enfant, elle ne s'est point sauvée... non, non... elle est restée...
elle m'a attendu... je crois bien même, daroga, qu'elle a un peu...
oh! pas beaucoup... mais un peu, comme une fiancée vivante, tendu
son front... Et... et... je l'ai... embrassée!... Moi!... moi!... moi!... Et
elle n'est pas morte!... Et elle est restée tout naturellement à côté de
moi, après que je l'ai eu embrassée, comme ça... sur le front... Ab!
que c'est bon, daroga, d'embrasser quelqu'un!... Tu ne peux pas
savoir, toi!... Mais moi! moi!... Ma mère, daroga, ma pauvre
misérable mère n'a jamais voulu que je l'embrasse... Elle se
sauvait... en me jetant mon masque!... ni aucune femme!...
jamais!... jamais!... Ah! ah! ah! Alors, n'est-ce pas?... d'un pareil
bonheur, n'est-ce pas, j'ai pleuré. Et je suis tombé en pleurant à ses
pieds... et j'ai embrassé ses pieds... ses petits pieds, en pleurant...
Toi aussi tu pleures, daroga; et elle aussi pleurait... l'ange a
pleuré!...
Comme il racontait ces choses, Erik sanglotait et le Persan, en effet,
n'avait pu retenir ses larmes devant cet homme masqué qui, les
épaules secouées, les mains à la poitrine, tantôt râlait de douleur et
tantôt d'attendrissement.
—... Oh! daroga, j'ai senti ses larmes couler sur mon front à moi! à
moi! à moi! Elles étaient chaudes... elles étaient douces! elles
allaient partout sous mon masque, ses larmes! elles allaient se mêler
à mes larmes dans mes yeux!... elles coulaient jusque dans ma
bouche... Ah! ses larmes à elle, sur moi! Écoute, daroga, écoute, ce
que j'ai fait... J'ai arraché mon masque pour ne pas perdre une seule
de ses larmes... Et elle ne s'est pas enfuie!... Et elle n'est pas morte!
Elle est restée vivante, à pleurer... sur moi... avec moi... Nous avons
pleuré ensemble!... Seigneur du ciel! vous m'avez donné tout le
bonheur du monde!...
Et Erik s'était effondré, râlant sur le fauteuil.
—Ah! Je ne vais pas encore mourir... tout de suite... mais laisse-moi
pleurer! avait-il dit au Persan.
Au bout d'un instant, l'Homme au masque avait repris:
—Écoute, daroga... écoute bien cela... pendant que j'étais à ses
pieds ...j'ai entendu qu'elle disait, «Pauvre malheureux Erik!» et elle
a pris ma main!... Moi, je n'ai plus été, tu comprends, qu'un pauvre
chien prêt à mourir pour elle... comme je te le dis, daroga!
«Figure-toi que j'avais dans la main un anneau, un anneau d'or que
je lui avais donné... qu'elle avait perdu... et que j'ai retrouvé... une
alliance, quoi!... Je le lui ai glissé dans sa petite main et je lui ai dit:
Tiens!... prends ça!... prends ça pour toi... et pour lui... Ce sera mon
cadeau de noces... le cadeau du pauvre malheureux Erik... Je sais
que tu l'aimes, le jeune homme... ne pleure plus!... Elle m'a
demandé, d'une voix bien douce, ce que je voulais dire; alors, je lui
ai fait comprendre, et elle a compris tout de suite que je n'étais pour
elle qu'un pauvre chien prêt à mourir... mais qu'elle, elle pourrait se
marier avec le jeune homme quand elle voudrait, parce qu'elle avait
pleuré avec moi... Ah! daroga... tu penses... que... lorsque je lui
disais cela, c'était comme si je découpais bien tranquillement mon
cœur en quatre, mais elle avait pleuré avec moi... et elle avait dit:
«Pauvre malheureux Erik!...»
L'émotion d'Erik était telle qu'il dut avertir le Persan de ne point le
regarder, car il étouffait et il était dans la nécessité d'ôter son
masque. À ce propos le daroga m'a raconté qu'il était allé lui-même
à la fenêtre et qu'il l'avait ouverte le cœur soulevé de pitié, mais en
prenant grand soin de fixer la cime des arbres du jardin des Tuileries
pour ne point rencontrer le visage du monstre.
—Je suis allé, avait continué Erik, délivrer le jeune homme et je lui ai
dit de me suivre auprès de Christine... Ils se sont embrassés devant
moi dans la chambre Louis-Philippe... Christine avait mon anneau...
J'ai fait jurer à Christine que lorsque je serais mort elle viendrait une
nuit, en passant par le Lac de la rue Scribe, m'enterrer en grand
secret avec l'anneau d'or qu'elle aurait porté jusqu'à cette minute-
là... je lui ai dit comment elle trouverait mon corps et ce qu'il fallait
en faire... Alors, Christine m'a embrassé pour la première fois, à son
tour, là, sur le front... (ne regarde pas, daroga!) là, sur le front... sur
mon front à moi!... (ne regarde pas, daroga!) et ils sont partis tous
les deux... Christine ne pleurait plus..., moi seul, je pleurais...
daroga, daroga... si Christine tient son serment, elle reviendra
bientôt!...
Et Erik s'était tu. Le Persan ne lui avait plus posé aucune question. Il
était rassuré tout à fait sur le sort de Raoul de Chagny et de
Christine Daaé, et aucun de ceux de la race humaine n'aurait pu,
après l'avoir entendue cette nuit-là, mettre en doute la parole d'Erik
qui pleurait.
Le monstre avait remis son masque et rassemblé ses forces pour
quitter le daroga. Il lui avait annoncé que, lorsqu'il sentirait sa fin
très prochaine, il lui enverrait, pour le remercier du bien que celui-ci
lui avait voulu autrefois, ce qu'il avait de plus cher au monde: tous
les papiers de Christine Daaé, qu'elle avait écrits dans le moment
même de cette aventure à l'intention de Raoul, et qu'elle avait
laissés à Erik, et quelques objets qui lui venaient d'elle, deux
mouchoirs, une paire de gants et un nœud de soulier. Sur une
question du Persan, Erik lui apprit que les deux jeunes gens aussitôt
qu'ils s'étaient vus libres, avaient résolu d'aller chercher un prêtre au
fond de quelque solitude où ils cacheraient leur bonheur et qu'ils
avaient pris, dans ce dessein, «la gare du Nord du; Monde». Enfin
Erik comptait sur le Persan pour, aussitôt que celui-ci aurait reçu les
reliques et les papiers promis, il annonçât sa mort aux deux jeunes
gens. Il devrait pour cela payer une ligne aux annonces
nécrologiques du journal l'Époque.
C'était tout.
Le Persan avait reconduit Erik jusqu'à la porte de son appartement
et Darius l'avait accompagné jusque sur le trottoir, en le soutenant.
Un fiacre attendait. Erik y monta. Le Persan, qui était revenu à la
fenêtre, l'entendit dire au cocher: «Terre-plein de l'Opéra».
Et puis, le fiacre s'était enfoncé dans la nuit. Le Persan avait, pour la
dernière fois, vu le pauvre malheureux Erik.
Trois semaines plus tard, le journal l'Époque avait publié cette
annonce nécrologique:
«ERIK EST MORT.»
ÉPILOGUE
Updated editions will replace the previous one—the old editions will
be renamed.
1.D. The copyright laws of the place where you are located also
govern what you can do with this work. Copyright laws in most
countries are in a constant state of change. If you are outside the
United States, check the laws of your country in addition to the
terms of this agreement before downloading, copying, displaying,
performing, distributing or creating derivative works based on this
work or any other Project Gutenberg™ work. The Foundation makes
no representations concerning the copyright status of any work in
any country other than the United States.
1.E.6. You may convert to and distribute this work in any binary,
compressed, marked up, nonproprietary or proprietary form,
including any word processing or hypertext form. However, if you
provide access to or distribute copies of a Project Gutenberg™ work
in a format other than “Plain Vanilla ASCII” or other format used in
the official version posted on the official Project Gutenberg™ website
(www.gutenberg.org), you must, at no additional cost, fee or
expense to the user, provide a copy, a means of exporting a copy, or
a means of obtaining a copy upon request, of the work in its original
“Plain Vanilla ASCII” or other form. Any alternate format must
include the full Project Gutenberg™ License as specified in
paragraph 1.E.1.
• You pay a royalty fee of 20% of the gross profits you derive
from the use of Project Gutenberg™ works calculated using the
method you already use to calculate your applicable taxes. The
fee is owed to the owner of the Project Gutenberg™ trademark,
but he has agreed to donate royalties under this paragraph to
the Project Gutenberg Literary Archive Foundation. Royalty
payments must be paid within 60 days following each date on
which you prepare (or are legally required to prepare) your
periodic tax returns. Royalty payments should be clearly marked
as such and sent to the Project Gutenberg Literary Archive
Foundation at the address specified in Section 4, “Information
about donations to the Project Gutenberg Literary Archive
Foundation.”
• You comply with all other terms of this agreement for free
distribution of Project Gutenberg™ works.
1.F.
1.F.4. Except for the limited right of replacement or refund set forth
in paragraph 1.F.3, this work is provided to you ‘AS-IS’, WITH NO
OTHER WARRANTIES OF ANY KIND, EXPRESS OR IMPLIED,
Welcome to our website – the ideal destination for book lovers and
knowledge seekers. With a mission to inspire endlessly, we offer a
vast collection of books, ranging from classic literary works to
specialized publications, self-development books, and children's
literature. Each book is a new journey of discovery, expanding
knowledge and enriching the soul of the reade
Our website is not just a platform for buying books, but a bridge
connecting readers to the timeless values of culture and wisdom. With
an elegant, user-friendly interface and an intelligent search system,
we are committed to providing a quick and convenient shopping
experience. Additionally, our special promotions and home delivery
services ensure that you save time and fully enjoy the joy of reading.
ebooknice.com