0

我在一家公司工作,该公司拥有数千份文档,主要是 pdf,存储在其网络服务器上的文件夹中。它们主要是他们所携带的不同品牌的不同产品的用户手册和技术文档。他们有一个网页,通过递归地遍历它们,当前显示文件夹中所有文档的链接,然后根据文件路径为每个图像生成一个 URL。

经理担心任何时候有人更改保存图像的服务器上的顶级文件夹的名称,它基本上会“破坏”代码,因为这些顶级名称在应用程序中是硬编码的。他希望将所有 URL 都存储在数据库中以缓解此问题,并要求我将 Web 服务器上的当前文件夹结构复制到 SQL 数据库中,然后将所有 URL 放入该数据库中。从我所做的研究来看,在关系数据库中实现这样的层次结构并非易事,而且我不是 DBA - 我是 Web 开发人员。

所以我现在的问题实际上是如何将当前在 Web 服务器上的所有数千张图像的 URL 获取到数据库中?我在想也许只创建一个名为“Brands”的简单表,其中包含品牌的根 URL,然后是另一个名为“Image links”或类似的表,然后编写一个小实用程序来简单地遍历所有图像 URL 和将它们插入该表 - 这听起来像是要走的路吗?

4

1 回答 1

0

在我看来,您可以使用用 C# 或 PowerShell 编写的简单命令行程序轻松导入所有文件夹和文件名,该程序从根目录开始并迭代所有文件夹和文件。你可以有这样的表:

CREATE TABLE dbo.Folders
(
  FolderID   INT IDENTITY(1,1) PRIMARY KEY,
  ParentID   INT NULL FOREIGN KEY REFERENCES dbo.Folders(FolderID),
  FolderName NVARCHAR(255) NOT NULL
  -- , ... other columns ...
);

CREATE TABLE dbo.Documents
(
  DocumentID INT IDENTITY(1,1) PRIMARY KEY,
  FolderID   INT NOT NULL FOREIGN KEY REFERENCES dbo.Folders(FolderID),
  DocName    NVARCHAR(255) NOT NULL
  -- , ... other columns ...
);

您可以使用Directory.GetFiles()之类的内容填充表格,这将允许您遍历文件夹和文件。您还可以编写一个函数来展平路径,这样您就不必在构建路径时遍历整个层次结构 - 但基于上述内容,重命名文件夹并且仍然始终生成正确的路径而不进行更新应该是非常简单的每个文件(尽管您必须更改文件夹并更新数据库并使它们保持同步)。只是一个带有一些虚构数据的例子:

INSERT dbo.Folders(ParentID, FolderName) SELECT NULL, N'root';
INSERT dbo.Folders(ParentID, FolderName) SELECT 1, N'sub1';
INSERT dbo.Folders(ParentID, FolderName) SELECT 1, N'sub2';
INSERT dbo.Folders(ParentID, FolderName) SELECT 2, N'subsub1';
INSERT dbo.Folders(ParentID, FolderName) SELECT 4, N'subsubsub1';

INSERT dbo.Documents(FolderID, DocName) SELECT 5, N'foo.pdf';
INSERT dbo.Documents(FolderID, DocName) SELECT 5, N'bar.pdf';

在给定 DocumentID 的情况下,这是一个可以展平路径的函数:

CREATE FUNCTION dbo.ShowFullPath
(
    @FolderID int,
    @DocName  nvarchar(255)
)
RETURNS nvarchar(max)
AS
BEGIN
    DECLARE @FullPath nvarchar(max);

    ;WITH cte AS 
    (
      SELECT FolderID, FolderName, ParentID, rn = 1
        FROM dbo.Folders
        WHERE FolderID = @FolderID
      UNION ALL
      SELECT parent.FolderID, parent.FolderName, 
          parent.ParentID, child.rn + 1
        FROM dbo.Folders AS parent
        INNER JOIN cte AS child
        ON parent.FolderID = child.ParentID
    )
    SELECT @FullPath = STUFF((SELECT N'/' + FolderName 
       FROM cte ORDER BY rn DESC 
       FOR XML PATH(''),
       TYPE).value(N'./text()[1]', N'nvarchar(max)'), 1, 1, N'')
       + N'/' + @DocName
    FROM cte;

    RETURN(@FullPath);
END
GO

因此,当您需要检索给定文档的路径时,您始终可以在运行时调用它(并且您可以更改一个函数或添加一个采用 DocumentID 的包装器,并提供 FolderID 和 DocName 参数),但它可能会做更多为此只使用计算列是有意义的(不幸的是,您将无法保留该列)。

ALTER TABLE dbo.Documents ADD FullPath 
  AS CONVERT(NVARCHAR(MAX), dbo.ShowFullPath(FolderID, DocName));

SELECT DocumentID, FolderID, DocName, FullPath FROM dbo.Documents;

结果:

DocumentID FolderID DocName FullPath
1          5        foo.pdf root/sub1/subsub1/subsubsub1/foo.pdf
2          5        bar.pdf root/sub1/subsub1/subsubsub1/bar.pdf

或者您可以创建一个视图:

CREATE VIEW dbo.vDocuments
AS
  SELECT DocumentID, FolderID, DocName, dbo.ShowFullPath(FolderID, DocName)
  FROM dbo.Documents;
于 2012-05-14T17:39:41.600 回答