Импорт и сохранение URL-адресов изображений в базе данных Sql - необходим совет

Я работаю в компании, у которой есть тысячи документов, в основном в формате PDF, которые хранятся в папках на их веб-сервере. В основном это руководства пользователя и техническая документация для различных продуктов разных брендов, которые они продают. У них есть веб-страница, которая в настоящее время отображает ссылки на все документы в папках, рекурсивно просматривая их, а затем генерируя URL-адрес для каждого изображения на основе пути к файлу.

Менеджер обеспокоен тем фактом, что каждый раз, когда кто-то меняет имя папки верхнего уровня на сервере, где хранятся изображения, это в основном «ломает» код, поскольку эти имена верхнего уровня жестко запрограммированы в приложении. Он хочет, чтобы все URL-адреса хранились в базе данных, чтобы решить эту проблему, и поручил мне в основном реплицировать текущую структуру папок на веб-сервере в базе данных SQL, а затем получить все URL-адреса в эту базу данных. Судя по проведенным мною исследованиям, реализовать подобную иерархическую структуру в реляционной базе данных - нетривиальная задача, и я не администратор баз данных - я веб-разработчик.

Итак, мой вопрос: как мне получить URL-адреса всех тысяч изображений, которые в настоящее время находятся на веб-сервере, в базе данных? Я подумал, может быть, создать простую таблицу под названием «Бренды», которая содержит корневые URL-адреса для брендов, затем еще одну таблицу с названием «Ссылки на изображения» или что-то в этом роде, а затем написать небольшую утилиту для простого перебора всех URL-адресов изображений и вставьте их в эту таблицу - это похоже на путь?


person quantum kev    schedule 14.05.2012    source источник
comment
Используйте перезапись URL, чтобы перезаписать запросы с нового имени папки на старое.   -  person vcsjones    schedule 14.05.2012


Ответы (1)


Мне кажется, что вы можете легко импортировать все имена папок и файлов с помощью простой программы командной строки, написанной на 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, 'root';
INSERT dbo.Folders(ParentID, FolderName) SELECT 1, 'sub1';
INSERT dbo.Folders(ParentID, FolderName) SELECT 1, 'sub2';
INSERT dbo.Folders(ParentID, FolderName) SELECT 2, 'subsub1';
INSERT dbo.Folders(ParentID, FolderName) SELECT 4, 'subsubsub1';

INSERT dbo.Documents(FolderID, DocName) SELECT 5, 'foo.pdf';
INSERT dbo.Documents(FolderID, DocName) SELECT 5, '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 '/' + FolderName 
       FROM cte ORDER BY rn DESC 
       FOR XML PATH('')), 1, 1, '')
       + '/' + @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;
person Aaron Bertrand    schedule 14.05.2012
comment
Спасибо за ответ - это определенно звучит как хороший способ сделать это. Тем не менее, все равно будет необходимо синхронизировать базу данных с именами папок, и мне обязательно нужно будет сообщить об этом моему боссу. - person quantum kev; 14.05.2012
comment
Что ж, вам может потребоваться строгий контроль над тем, кто может изменять эти таблицы и / или переименовывать папки в Windows по своему усмотрению. Тем не менее, вы всегда можете создать главное приложение, которое может войти и полностью перестроить представление в базе данных из корня или любой произвольной папки ... - person Aaron Bertrand; 14.05.2012
comment
Вероятно, это единственное, чего нельзя избежать, если отделить сам файл от указателя, хранящегося в базе данных. Вы можете заглянуть в FILESTREAM (или FileTable в SQL Server 2012), но я не уверен, что они лучше подойдут для ваших нужд. Или вы можете просто предложить ему инвестировать в SharePoint - вот почему люди больше не создают эти вещи вручную с нуля. - person Aaron Bertrand; 14.05.2012
comment
Вау, спасибо за подробный ответ и пример. Я неплохо разбираюсь в интерфейсной разработке, но не уверен, что когда-либо смог бы придумать этот SQL-код. Я ценю вашу помощь и посмотрю, что мой босс и его приятель думают о таком подходе. И +1 к идее Sharepoint - именно мои мысли! Ржу не могу - person quantum kev; 14.05.2012