Модераторы: gambit

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Документ MS Office (Word или Excel) в БД, как оптимальнее хранить? 
:(
    Опции темы
RedButterfly
Дата 3.9.2008, 13:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Учусь
*


Профиль
Группа: Участник
Сообщений: 132
Регистрация: 4.7.2005
Где: Уфа->Москва

Репутация: нет
Всего: нет



Цитата(Idsa @ 3.9.2008,  13:36)
Цитата(RedButterfly @  3.9.2008,  16:59 Найти цитируемый пост)
Чтобы он хранился в виде поля image в базе данных.

Image - устаревший тип. Рекомендуется использовать varchar(max).

Цитата(RedButterfly @  3.9.2008,  16:59 Найти цитируемый пост)
Чтобы залить его в базу и вытаскивать оттуда.

Весьма спорное решение. Все-таки DBA сходятся в том, что blob-данные лучше хранить на жестком диске, а в базе хранить только указатель на них.
Я сам недавно столкнулся дилеммой "хранить blob-данные в базе или нет". Провел тестирование под MS SQL Server 2005. Пришел к выводу, что на производительность запросов (тех, которые не задействуют сами blob-данные) хранение blob-данных в базе не влияет (насколько я помню, эти данные просто хранятся в отдельной области в базе данных, поэтому их присутствие не сказывается на производительности). Однако есть еще пара нюансов. Например, уже так просто не откроешь в Management Studio (или в любом другом клиенте) табличку (а в процессе разработки это очень удобно): открытие таблицы, которая весит гигабайт (это так, для начала smile ) занимает гораздо больше времени, чем хотелось бы. Кроме того, скачивание файлов из базы имеет ряд тонкостей:
1. Скачивать файл на клиент полностью нельзя, т. к. передача на клиент, например, 2 гигабайт данных просто убьет среднестатистическую тачку (OutOfMemoryException). Нужно использовать последовательное считывание и обработку (например, запись на жесткий диск на клиенте). Пример такого считывания я уже как-то приводил.
2. Если считывать большие файлы из базы, очень долго будет открыт connection к базе. Насколько я могу судить, connection к базе - гораздо более серьезный ресурс, нежели connection к серверу (при традиционном хранении файлов). Кроме того, если я не ошибаюсь, на некоторые СУБД есть лицензии, которые ограничивают количество одновременных соединений.

очень интересные замечания smile

Дело в том, что я до конца не могу определиться как лучше всего сделать прогу, а именно:

в программе есть TreeView, кликая на ветки которого, пользователи, сидящие в разных местах (будет распределенное приложение) будут открывать эти файлы - документы Word (для начала)

будут создавать, изменять, удалять, перемещать по дереву и т.д.

пишу под vs2005 + sqlserver2005

файлы большие, тяжелые и с разнообразным содержимым

кучу файлов потом надо будет сливать в один (соединить документы ворд) и такой файл будет весить метров 200-300-400...естественно его тоже будут смотреть...)))

Руководство желает, чтобы вся информация хранилась в базе данных.
Мне же кажется удобным и безопасным (кто знает что может стать с этой БД) хранение и в БД и в защищенном месте в виде файлов.

С удовольствием выслушаю советы smile


PM MAIL ICQ Skype   Вверх
Idsa
Дата 3.9.2008, 14:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник
Сообщений: 2086
Регистрация: 5.12.2006
Где: Томск

Репутация: 15
Всего: 62



Цитата(RedButterfly @  3.9.2008,  17:56 Найти цитируемый пост)
Мне же кажется удобным и безопасным (кто знает что может стать с этой БД) хранение и в БД и в защищенном месте в виде файлов.

Хранение и там, и там - пустая трата ресурсов. Нужно определиться с местом хранения и периодически делать бекапы.
Я сейчас заканчиваю проект с очень похожей структурой. У меня файлы хранятся в файловой системе, причем каталоги воссоздают то самое дерево. Гемороя, конечно, больше, нежели с хранением файлов в базе, но мне религия не позволяет захламлять базу большими файлами.


--------------------
Мой блог: alexidsa.blogspot.com
PM MAIL ICQ   Вверх
RedButterfly
Дата 3.9.2008, 15:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Учусь
*


Профиль
Группа: Участник
Сообщений: 132
Регистрация: 4.7.2005
Где: Уфа->Москва

Репутация: нет
Всего: нет



интересный проект делаете smile

на будущее посоветуйте пожалуйста литературу по распределенным приложениям smile а то я не знаю даже с какой стороны подойти к этой части задаче.


скоро выложу что у меня получилось на этом этапе

smile
PM MAIL ICQ Skype   Вверх
Idsa
Дата 3.9.2008, 15:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник
Сообщений: 2086
Регистрация: 5.12.2006
Где: Томск

Репутация: 15
Всего: 62



Цитата(RedButterfly @  3.9.2008,  19:04 Найти цитируемый пост)
на будущее посоветуйте пожалуйста литературу по распределенным приложениям smile

Тот проект, про который я говорил, - ASP.NET портал.
В Вашем же случае я посоветовал бы WCF.


--------------------
Мой блог: alexidsa.blogspot.com
PM MAIL ICQ   Вверх
RedButterfly
Дата 4.9.2008, 06:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Учусь
*


Профиль
Группа: Участник
Сообщений: 132
Регистрация: 4.7.2005
Где: Уфа->Москва

Репутация: нет
Всего: нет



Цитата(Idsa @ 3.9.2008,  15:25)
Цитата(RedButterfly @  3.9.2008,  19:04 Найти цитируемый пост)
на будущее посоветуйте пожалуйста литературу по распределенным приложениям smile

Тот проект, про который я говорил, - ASP.NET портал.
В Вашем же случае я посоветовал бы WCF.

А можно расшифровать? smile
PM MAIL ICQ Skype   Вверх
Idsa
Дата 4.9.2008, 06:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник
Сообщений: 2086
Регистрация: 5.12.2006
Где: Томск

Репутация: 15
Всего: 62



Цитата(RedButterfly @  4.9.2008,  10:40 Найти цитируемый пост)
А можно расшифровать? smile 

Что именно расшифровать?


--------------------
Мой блог: alexidsa.blogspot.com
PM MAIL ICQ   Вверх
MasterOfCode
Дата 4.9.2008, 08:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


elwin
**


Профиль
Группа: Участник
Сообщений: 740
Регистрация: 24.4.2008
Где: World.Russia.Tyum en

Репутация: 4
Всего: 27



Хранение данных используя нереляционные хранилища тоже чреваты некими сложностями. Например:
1. Доступ к файлам учетных записей домена.
2. Отсутствие резервного копирования.

поясню:
1. Столкнулся когда писал приложение, в БД хранились пути к файлам, пользователь указывает что хотел бы просмотреть этот документ, а его не пускает туда, как оказалось такова политика отдела безопасности. А пользователь видит еще те файлы которые ему видеть не надо, его туда даже не пустит. 
Еще почему то когда учетной был дан доступ, фреймверк переодически стрелял с ошибкой доступа, получался доступ к файлу через раз.
2. Здесь преимущества тоже за БД, у нее есть хорошее свойство как backup/restore, вслучаи чего можно восстановить, если же полетит хард у сервера (что не редкость), то восттановить сложновато.

Но все же это вопрос на который нет однозначного ответа. У нас маленькие файлы хранятся в БД. Большие хранятся на сервере в файловой системе. файловая система дублируется, 3 сервера, все 3 в разных городах, в случае чего, восстановить можно и файлы.


--------------------
user posted image
PM ICQ   Вверх
RedButterfly
Дата 4.9.2008, 08:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Учусь
*


Профиль
Группа: Участник
Сообщений: 132
Регистрация: 4.7.2005
Где: Уфа->Москва

Репутация: нет
Всего: нет



Цитата(Idsa @ 4.9.2008,  06:44)
Цитата(RedButterfly @  4.9.2008,  10:40 Найти цитируемый пост)
А можно расшифровать? smile 

Что именно расшифровать?

расшифровала smile
WCF-Windows Communication Foundation
так?

Добавлено через 3 минуты и 37 секунд
Цитата(MasterOfCode @ 4.9.2008,  08:20)
Хранение данных используя нереляционные хранилища тоже чреваты некими сложностями. Например:
1. Доступ к файлам учетных записей домена.
2. Отсутствие резервного копирования.

поясню:
1. Столкнулся когда писал приложение, в БД хранились пути к файлам, пользователь указывает что хотел бы просмотреть этот документ, а его не пускает туда, как оказалось такова политика отдела безопасности. А пользователь видит еще те файлы которые ему видеть не надо, его туда даже не пустит. 
Еще почему то когда учетной был дан доступ, фреймверк переодически стрелял с ошибкой доступа, получался доступ к файлу через раз.
2. Здесь преимущества тоже за БД, у нее есть хорошее свойство как backup/restore, вслучаи чего можно восстановить, если же полетит хард у сервера (что не редкость), то восттановить сложновато.

Но все же это вопрос на который нет однозначного ответа. У нас маленькие файлы хранятся в БД. Большие хранятся на сервере в файловой системе. файловая система дублируется, 3 сервера, все 3 в разных городах, в случае чего, восстановить можно и файлы.

сервер один..и он без зеркал...

можете дать примеры книг/статей/прочего для написания приложения работающего по сети? 


smile
PM MAIL ICQ Skype   Вверх
Wanderer2019
Дата 4.9.2008, 11:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 937
Регистрация: 3.12.2004
Где: Санкт-Петербург/П рага

Репутация: 1
Всего: 17



Цитата(RedButterfly @  3.9.2008,  13:56 Найти цитируемый пост)
кучу файлов потом надо будет сливать в один (соединить документы ворд) и такой файл будет весить метров 200-300-400...естественно его тоже будут смотреть...)))


Вы для начала попробуйте открыть файл размером 400 метров вордом =)
PM ICQ MSN   Вверх
RedButterfly
Дата 4.9.2008, 11:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Учусь
*


Профиль
Группа: Участник
Сообщений: 132
Регистрация: 4.7.2005
Где: Уфа->Москва

Репутация: нет
Всего: нет



Цитата(Wanderer2019 @ 4.9.2008,  11:20)
Цитата(RedButterfly @  3.9.2008,  13:56 Найти цитируемый пост)
кучу файлов потом надо будет сливать в один (соединить документы ворд) и такой файл будет весить метров 200-300-400...естественно его тоже будут смотреть...)))


Вы для начала попробуйте открыть файл размером 400 метров вордом =)

нуу) он завсинет же)....
но пользователи верят, что смогут терпеливо открывать такие файлы... ))

пока вот что у меня получилось

Это открытие файла и копирование его в другое место.

Код


  private void menuItemOpen_Click(object sender, System.EventArgs e)        //реакция на "Открыть"
        {
    if(openFileDialog.ShowDialog()==DialogResult.OK) // Если выбрали файл и нажали ОК
            {

                Word.ApplicationClass wordApp = new Word.ApplicationClass();
                object fileName = openFileDialog.FileName;
                object confirmConversions = Type.Missing;
                object readOnly = Type.Missing;
                object addToRecentFiles = Type.Missing;
                object passwordDocument = Type.Missing;
                object passwordTemplate = Type.Missing;
                object revert = Type.Missing;
                object writePasswordDocument = Type.Missing;
                object writePasswordTemplate = Type.Missing;
                object format = Type.Missing;
                object encoding = Type.Missing;
                object visible = Type.Missing;
                object openConflictDocument = Type.Missing;
                object openAndRepair = Type.Missing;
                object documentDirection = Type.Missing;
                object noEncodingDialog = Type.Missing;
                //wordApp.Documents.Open(ref fileName, ref confirmConversions, ref readOnly,
                //    ref addToRecentFiles, ref passwordDocument, ref passwordTemplate, ref revert,
                //    ref writePasswordDocument, ref writePasswordTemplate, ref format, ref encoding,
                //    ref visible, ref openConflictDocument, ref openAndRepair, ref documentDirection,
                //    ref noEncodingDialog);
               

                string pathFile = openFileDialog.FileName;      // В строку записали полный путь к файлу.

                Word.Document doc = wordApp.Documents.Add(ref empty, ref empty, ref empty, ref empty);

                wordApp.Visible = true;     // Показали приложение Word.
                wordApp.Activate();        // Активировали документ.

                doc.Select(); 
                
                byte[] data = GetBinaryData(pathFile);       // Делаем из документа байты.
                doc.Close(ref rfalse, ref empty, ref empty);

                Word.Document restoredDoc = wordApp.Documents.Add(ref empty, ref empty, ref empty, ref empty);
                RestoreFromBinaryData(data, restoredDoc);
                object rfileName = "c:\\1.doc";
             
                restoredDoc.Close(ref rfalse, ref empty, ref empty);
                wordApp.Quit(ref empty, ref empty, ref empty);
              //Job_BD();
            }            
    }


Этот метод делает из файла байты:
Код

        static byte[] GetBinaryData(string pathFile)        // Метод "берем из ворда".
        {
             FileStream fileStream = File.Open(pathFile, FileMode.Open);
            byte[] file_bytes = new byte[fileStream.Length];
            fileStream.Read(file_bytes, 0, file_bytes.Length);      // Теперь в переменной file_bytes хранится файл.
//Заодно пытаюсь положить файл в MemoryStream))
            //MemoryStream memoryStreamGet = new MemoryStream();     // Поток в памяти.
            //memoryStreamGet.Write(file_bytes, 0, file_bytes.Length);       // Записали в поток байты.
            //memoryStreamGet.Close();
            //return memoryStream.GetBuffer();        // Вернуть буфер потока.
            return file_bytes;
            fileStream.Close();     // Закрываем поток.
        }

а так из байтов документ ворд получается...
Код

static void RestoreFromBinaryData(byte[] bin, Word.Document targetDoc)        // Метод "ложим в ворд"
        {  FileStream fileStream = new FileStream("c:\\1.doc",FileMode.Create,FileAccess.Write);
             
            fileStream.Write(bin, 0, bin.Length);       // Записали буфер в файловый поток.

            targetDoc.Select();        

            targetDoc.Application.Selection.Paste();        // Вставила в документ Ворд.
            fileStream.Close();
            //MemoryStream memoryStreamRestore = new MemoryStream();     // Поток в памяти.
            //memoryStreamRestore.WriteTo(fileStream);        // Записала в память (поток) файловый поток.
            //byte[] bytesInMemoty = memoryStreamRestore.ToArray();       //Записала в массив байтов содержимое потока.
            //memoryStreamRestore.Close();
        }


Я вот думаю, нужно ли эти документы сериализовать?
PM MAIL ICQ Skype   Вверх
MasterOfCode
Дата 4.9.2008, 12:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


elwin
**


Профиль
Группа: Участник
Сообщений: 740
Регистрация: 24.4.2008
Где: World.Russia.Tyum en

Репутация: 4
Всего: 27



Так на вскидочку.
Код

fileStream.Read(file_bytes, 0, file_bytes.Length);

Если файл будет 400 Мб, эта строка вызовет зависание программы.

Код

return file_bytes;
fileStream.Close();

fileStream.Close(); не выполнится, т.к. процедура прекратит работать строчкой выше.


--------------------
user posted image
PM ICQ   Вверх
RedButterfly
Дата 4.9.2008, 13:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Учусь
*


Профиль
Группа: Участник
Сообщений: 132
Регистрация: 4.7.2005
Где: Уфа->Москва

Репутация: нет
Всего: нет



учла smile
PM MAIL ICQ Skype   Вверх
RedButterfly
Дата 5.9.2008, 06:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Учусь
*


Профиль
Группа: Участник
Сообщений: 132
Регистрация: 4.7.2005
Где: Уфа->Москва

Репутация: нет
Всего: нет



что-то я не пойму :(
если вот так добавить значение в базу данных - оно добавляется из TextBox: 
я думаю, что тут написано криво, но работает....

Код

 private void PressButton_Click(object sender, System.EventArgs e)
        {
            //MessageBox.Show("Работать негры!!!");
            try
            {
                using (SqlConnection sqlConnection = new SqlConnection("Data Source=OP-093;Initial Catalog=Proektik;Integrated Security=True"))
            {
                string Name = textBox.Text;
                dataGridView.DataSource = null;
                    SqlCommand insertCommand = new SqlCommand("INSERT INTO TablePro (Name) VALUES (@Name);", sqlConnection);

                insertCommand.Parameters.Add("@Name", Name);
                sqlConnection.Open();
                sqlDataAdapter.InsertCommand = insertCommand;
                insertCommand.ExecuteNonQuery();
                sqlDataAdapter.Update(proektikDataSet, "TablePro");

                proektikDataSet.AcceptChanges();         // Принимаем изменения.
                
                sqlDataAdapter.Fill(proektikDataSet, "TablePro");

                dataGridView.DataSource = proektikDataSet.Tables["TablePro"].DefaultView;
                dataGridView.Refresh();
                sqlConnection.Close();
            }
            }
            catch(SqlException ex)
            {
                throw ex;        // Обработка универсальных исключений…   
            }
        }


а вот так не добавляет:

Код

private void menuItemOpen_Click(object sender, System.EventArgs e)        //реакция на "Открыть"
        {
    if(openFileDialog.ShowDialog()==DialogResult.OK) // Если выбрали файл и нажали ОК
            {

                Word.ApplicationClass wordApp = new Word.ApplicationClass();
               string pathFile = openFileDialog.FileName;      // В строку записали полный путь к файлу.

                Word.Document doc = wordApp.Documents.Add(ref empty, ref empty, ref empty, ref empty);

                wordApp.Visible = true;     // Показали приложение Word.
                wordApp.Activate();        // Активировали документ.

                doc.Select();
                
                byte[] data = GetBinaryData(pathFile);       // Делаем из документа байты.
                doc.Close(ref rfalse, ref empty, ref empty);

                Job_BD(data);
            }            
    }



где 

Код

 static byte[] GetBinaryData(string pathFile)        // Метод "берем из ворда".
        {
             FileStream fileStream = File.Open(pathFile, FileMode.Open);
            byte[] file_bytes = new byte[fileStream.Length];
            fileStream.Read(file_bytes, 0, file_bytes.Length);      // Теперь в переменной file_bytes хранится файл.
             fileStream.Close();     // Закрываем поток.
            return file_bytes;            
        }


вот тут 
Код

public void Job_BD(byte[] data)       // Функция для того чтобы положить файл в базу данных.
        {
            try
            {
                using (SqlConnection sqlConnection = new SqlConnection("Data Source=OP-093;Initial Catalog=Proektik;Integrated Security=True"))
                {
                    byte[] Text = data ;
                    dataGridView.DataSource = null;
            

                    SqlCommand insertCommand = new SqlCommand("INSERT INTO TablePro (Text) VALUES (@Text);", sqlConnection);

                    insertCommand.Parameters.Add("@Text", Text);
                    sqlDataAdapter.InsertCommand = insertCommand;
                    sqlConnection.Open();
                    insertCommand.ExecuteNonQuery();
                    sqlDataAdapter.Update(proektikDataSet, "TablePro");

                    proektikDataSet.AcceptChanges();         // Принимаем изменения.

                    sqlDataAdapter.Fill(proektikDataSet, "TablePro");

                    dataGridView.DataSource = proektikDataSet.Tables["TablePro"].DefaultView;
                    dataGridView.Refresh();
                    sqlConnection.Close();
                }
            }
            catch (SqlException ex)
            {
                //MessageBox.Show(ex.Message);
                throw ex;        // Обработка универсальных исключений…   
            }
                    
        }


выскакивает такое окошечко


Присоединённый файл ( Кол-во скачиваний: 7 )
Присоединённый файл  ______.JPG 51,81 Kb
PM MAIL ICQ Skype   Вверх
MasterOfCode
Дата 5.9.2008, 06:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


elwin
**


Профиль
Группа: Участник
Сообщений: 740
Регистрация: 24.4.2008
Где: World.Russia.Tyum en

Репутация: 4
Всего: 27



Код

insertCommand.Parameters.Add("@Text", SqlDbType.Image, Text.Length).Value = Text;


Так попробуй.


--------------------
user posted image
PM ICQ   Вверх
RedButterfly
Дата 5.9.2008, 09:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Учусь
*


Профиль
Группа: Участник
Сообщений: 132
Регистрация: 4.7.2005
Где: Уфа->Москва

Репутация: нет
Всего: нет



Цитата(MasterOfCode @ 5.9.2008,  06:35)
Код

insertCommand.Parameters.Add("@Text", SqlDbType.Image, Text.Length).Value = Text;


Так попробуй.

не помогло :(

выскакивают уже два окошкас одинаковой ошибкой, в которых говорится,что поле ожидает, что в него положат значение...и не дожидается...как я поняла....

на это


Код

    public void Job_BD(byte[] data)       // то ли тут байты не передаются

// Вызываемая вот так: Job_BD(data);

        {
            try
            {
                using (SqlConnection sqlConnection = new SqlConnection("Data Source=op-093;Initial Catalog=Proektik;Integrated Security=True"))
                {
                    byte[] Context = data ; // то ли тут не передаются

                   dataGridView.DataSource = null;

                   SqlCommand insertCommand = new SqlCommand("INSERT INTO TableProekt (Context) VALUES (@Context)", sqlConnection);

                    insertCommand.Parameters.Add("@Context",SqlDbType.Image, Context.Length);
                    sqlDataAdapter.InsertCommand = insertCommand;
                    sqlConnection.Open();
                   insertCommand.ExecuteNonQuery();
                    sqlDataAdapter.Update(dataSet, "TableProekt");

                    dataSet.AcceptChanges();         // Принимаем изменения.

                    sqlDataAdapter.Fill(dataSet, "TableProekt");

                    dataGridView.DataSource = dataSet.Tables["TableProekt"].DefaultView;
                   dataGridView.Refresh();
                    sqlConnection.Close();
                }
            }
            catch (SqlException ex)
            {
                MessageBox.Show(ex.Message);
                throw ex;        // Обработка универсальных исключений…   
            }


Присоединённый файл ( Кол-во скачиваний: 4 )
Присоединённый файл  _______3.jpg 157,42 Kb
PM MAIL ICQ Skype   Вверх
Страницы: (3) Все 1 [2] 3 
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
stab
mr.DUDA
Exception

Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов.

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, stab, mr.DUDA, Exception.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Базы данных под .NET | Следующая тема »


 




[ Время генерации скрипта: 0.1222 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.